<?php

namespace control;
/*
*销售单类
*/

class saleOrderClass extends adIndexClass
{
    private const page = 'saleOrder';
    private const table = 'sale_order';
    private const tableMx = 'sale_order_detail';
    private const title = '销售订单';
    public const  deliveryMethod = ['1' => '自提', '2' => '配送'];
    public const  scheduleState = ['否', '是', '否'];
    public array $stateOption = ['草稿', '待确认', '已确认'];

    /**
     * 字段初始化
     */
    public function fieldInit($fun): array
    {
        switch ($fun) {
            case 'clientOrderSearch':
                $tr = [
                    'orderNo'      => [
                        'name'  => '单据编号',
                        'width' => 200,
                        'sort'  => 1,
                    ],
                    'type'         => [
                        'name'  => "业务类型",
                        'width' => 200,
                    ],
                    'companyName'  => [
                        'name'  => "客户",
                        'width' => 200,
                    ],
                    'tags'         => [
                        'name'  => '单据标签',
                        'width' => 200,
                    ],
                    'manager'      => [
                        'name'  => '销售员',
                        'width' => 100,
                    ],
                    'num'          => [
                        'name'  => '数量',
                        'width' => 100,
                    ],
                    'money'        => [
                        'name'  => '订单金额(' . static::$unit . '）',
                        'width' => 100,
                        'sort'  => 1,
                    ],
                    'deliveryDate' => [
                        'name'  => '交货日期',
                        'width' => 100,
                        'sort'  => 1,
                    ],
                    'recordDate'   => [
                        'name'  => '单据日期',
                        'width' => 100,
                        'sort'  => 1,
                    ],
                    'state'        => [
                        'name'  => '状态',
                        'width' => 100,
                    ],
                ];
                break;
            default:
                $tr = [
                    'orderNo'         => [
                        'name'  => '单据编号',
                        'width' => 200,
                        'sort'  => 1,
                    ],
                    'companyName'     => [
                        'name'  => "客户",
                        'width' => 200,
                    ],
                    'tags'            => [
                        'name'  => "单据标签",
                        'width' => 200,
                    ],
                    'manager'         => [
                        'name'  => '销售员',
                        'width' => 100,
                    ],
                    'num'             => [
                        'name'  => '数量',
                        'width' => 100,
                        'sort'  => 1,
                    ],
//                    'send_num'        => [
//                        'name'  => '发货',
//                        'width' => 100,
//                        'sort'  => 1,
//                    ],
//                    'refund_num'      => [
//                        'name'  => '退货',
//                        'width' => 100,
//                        'sort'  => 1,
//                    ],
//                    'residue'         => [
//                        'name'  => '剩余',
//                        'width' => 100,
//                    ],
//                    'completion_rate' => [
//                        'name'  => '完成率',
//                        'width' => 100,
//                        'sort'  => 1,
//                    ],
                    'deliveryDate'    => [
                        'name'  => '交货日期',
                        'width' => 100,
                        'sort'  => 1,
                    ],
                    'recordDate'    => [
                        'name'  => '单据日期',
                        'width' => 100,
                        'sort'  => 1,
                    ],
//                    'money'           => [
//                        'name'  => '订单金额(' . static::$unit . ')',
//                        'width' => 120,
//                        'sort'  => 1,
//                    ],
                    'state'           => [
                        'name'  => '状态',
                        'width' => 100,
                    ],
                ];
        }
        return $tr;
    }

    /*列表页-查询条件*/
    public function clientOrderOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    "单据编号" => text(["name" => "orderNo"]) . hidden(["name" => "targetId", "value" => $this->get('id')]),
                    "销售员"  => selectMultiple(["name" => "stid", 'table' => " staff", 'sqlId' => 'stid', 'sqlField' => 'name']),
                    '单据日期' => text(["name" => "createTime", 'laydate' => ['type' => 'date', 'range' => '~']]),
                ],
                [
                    "状态" => select(["name" => "state", 'option' => ['草稿', '待确认', '已确认']]),
                ],
            ],
        ], 1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /**
     * 客户页卡销售单
     *
     * @return bool|string
     */
    public function clientOrder(): bool|string
    {
        $html   = $this->clientOrderOptions(false);
        $button = "";
        if ($this->power(self::page, "print")) {
            $button .= sprintf("<span onclick=\"batchPrint('%s', {targetId: '%s'})\" class='spanButton'>打印设置</span>\n", $this->get('cla'), $this->get('id'));
        }
        //返回
        $json['html'] = $this->search($html, layout: 'pop', toolButton: $button);
        return json_encode($json, 320);
    }

    public function clientOrderSearch(): bool|string
    {
        $khid = $this->post('targetId');
        //like查询数组
        $like = [
            "orderNo" => $this->post('orderNo'),
        ];
        //全等查询数组
        $equal = [
            "state" => $this->post('state'),
            "stid"  => $this->post('stid'),
            'coid'  => self::$coid,
        ];
        $kehu  = query("kehu", " khid = '$khid' ", "companyName");
        $and   = " and khid = '$khid'";
        if ($this->post('createTime')) {
            $and .= self::timeComparison($this->post('createTime'), 'date', 'recordDate');
        }
        //排序
        $orderBy = $this->listSort([
            "search" => $this->post('list_sort_key') ?: 'recordDate desc,time',
            "sort"   => $this->post('list_sort') ?: "desc",
            "array"  => [],
        ]);
        //生成查询语句
        $where = search([
                "="    => $equal,
                "like" => $like,
            ]) . $and;
        $page  = $this->page(["table" => self::table, "where" => $where, "order" => $orderBy['orderBy']]);
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = [""];
        //获取记录
        foreach ($page['array'] as $array) {
            //列表控件
            $dominate   = [
                "detail" => ["title" => self::title . "详情", "click" => "newIframe('" . self::title . "详情','" . root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=detail&id=' . $array['id'] . "')"],
            ];
            $closeSign  = $array['isClose'] ? "<span class='no-choose'></span>" : '';//关闭单据颜色显示标志
            $liButton[] = $this->dominate($dominate) . $closeSign;
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case "companyName":
                        $row[] = $kehu['companyName'];
                        break;
                    case "tags":
                        $tags  = orderTagClass::getTagName($array['id']);
                        $row[] = $tags;
                        break;
                    case "manager":
                        $row[] = self::findStaff($array['manager']);
                        break;
                    case "num":
                        $num   = find(['table' => self::tableMx, 'where' => "orderId = '$array[id]'", 'sum' => "num"]);
                        $row[] = $num;
                        break;
                    case "money":
                        $row[] = self::formattingFigure($array['money'], 'amount');
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        //生成页面
        $li = $this->li([
            "body"        => $body,
            "install"     => $installSearch,
            "button"      => ["html" => $liButton],
            "orderBySign" => $orderBy,
            "page"        => $page['para'],
        ]);
        //返回
        $json['html'] =
            "<form name='contractForm'>" .
            $li .
            "</form>" .
            machiningOrderClass::closeJs() .
            $page['button'] .
            clear;
        return json_encode($json, 320);
    }

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    "单据编号" => text(["name" => "orderNo"]),
                    "标签"   => text(["name" => "tages"]),
                    '客户名称' => clientProfileClass::kehuSelect(['title' => '']),
                ],
                [
                    '销售员'  => selectMultiple(["name" => "stid", 'table' => " staff", 'sqlId' => 'stid', 'sqlField' => 'name']),
                    "交货日期" => text(["name" => "createTime", 'laydate' => ['type' => 'date', 'range' => '~']]),
                    '按期交货' => select(["name" => "deliver_on_schedule", 'option' => [1 => '是', 0 => '否']]),
                ],
                [
                    "状态" => select(["name" => "state", 'option' => $this->stateOption]),
                ],
            ],
        ], 1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /*列表-查询条件*/
    public function home()
    {
        $html = $this->homeOptions(false);
        //控件
        $url    = root . "control/adIndex.html?cla=" . self::page;
        $button = "";
        if ($this->power(self::page, "edit")) {
            $button .= "<span onclick=\"newIframe('" . self::title . "详情','" . $url . "&fun=edit')\" class='spanButton'>新增</span>\n";
        }
        if ($this->power(self::page, "del")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'del'})\">删除</span>\n";
        }
//        if ($this->power(self::page, "edit")) {
//            $button .= " <span onclick=\"layer('orderTag','batchAddTags',{'table':'" . self::table . "','title':'" . self::title . "'})\" class='spanButton'>批量打标签</span>\n";
//        }
        if ($this->power(self::page, "close")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'close'})\">批量关闭</span>\n";
        }
//        if ($this->power(self::page, "print")) {
//            $button .= " <span onclick=\"batchPrint('" . $this->get('cla') . "')\" class='spanButton'>批量打印</span>\n";
//        }
//        if ($this->power(self::page, 'import')) {
//            $button .= "<span class='spanButton' onclick=\"layer('importTemplate','importFrame',{cla:'" . self::page . "'})\">导入</span>";
//        }
//        if (para('CSAIII') == '是') {
//            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'batchSure'})\">批量提交确认</span>\n";
//        }
//        if ($this->power(self::page, "edit")) {
//            $button .= "<span class='spanButton' onclick=\"layer('importTemplate','exportFrame',{cla:'" . self::page . "'})\">导出</span>";
//        }
        //返回
        return $this->homeFun($this->search($html, layout: 'pop', toolButton: $button));
    }

    /*客户列表-查询结果*/
    public function homeSearch()
    {
        //like查询数组
        $like = [
            "orderNo" => $this->post('orderNo'),
        ];
        //全等查询数组
        $equal = [
            "state" => $this->post('state'),
            "stid"  => $this->post('stid'),
            "khid"  => $this->post('khid'),
            'coid'  => self::$coid,
        ];
        $and   = '';
        if ($this->post('createTime')) {
            $and .= self::timeComparison($this->post('createTime'), 'date', 'deliveryDate');
        }
        //查询是否超期
        if ($this->post('deliver_on_schedule') != '') {
            if ($this->post('deliver_on_schedule') == 1) {
                $and .= " and deliver_on_schedule = 1 ";
            } else {
                $and .= " and deliver_on_schedule = 0 and unix_timestamp(curdate()) > unix_timestamp(deliveryDate) ";
            }
        }
        if ($this->post('tages')) {
            $and     .= " and (";
            $tagsArr = explode('，', $this->post('tages'));
            foreach ($tagsArr as $index => $tag) {
                $and .= $index == 0 ? "tags like '%" . $tag . "%'" : " and tags like '%" . $tag . "%'";
            }
            $and .= ")";
        }
        if (!$this->power(self::page, 'seeAll')) {
            $and .= " and (stid = '" . self::$stid . "' or manager = '" . self::$stid . "') ";
        }
        //排序
        $orderBy = $this->listSort([
            "search" => $this->post('list_sort_key') ?: 'recordDate desc,orderNo',
            "sort"   => $this->post('list_sort') ?: "desc",
            "array"  => [],
        ]);
        //获取查询结果
        $where                       = search(["like" => $like, "=" => $equal]) . $and;
        $page                        = $this->page(["table" => self::table, "where" => $where, "order" => $orderBy['orderBy']]);
        $_SESSION[self::page]['sql'] = $page['fullSql'];
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = [
            $this->checkAll("listForm", "listId"),
        ];
        //获取记录
        $url = root . "control/adIndex.html?cla=" . self::page;
        foreach ($page['array'] as $array) {
            //列表控件
            $dominate = [
                "box"     => ["name" => "listId", "value" => $array['id']],
                "edit"    => ["title" => "编辑", "click" => "newIframe('" . self::title . "详情','" . $url . "&fun=edit&id=" . $array['id'] . "')"],
                "detail"  => ["title" => self::title . "详情", "click" => "newIframe('" . self::title . "详情','" . $url . "&fun=detail&id=" . $array['id'] . "')"],
                'print'   => ['title' => '打印', 'click' => "window.open('" . root . "control/adIndex.html?cla=" . self::page . "&fun=printPage&id={$array['id']}')"],
                'track'   => ["title" => "单据追踪", "click" => "newIframe('单据追踪','" . root . "control/adIndex.html?cla=orderTrack&fun=home&orderType=销售订单&id=" . $array['id'] . "')"],
                'backCar' => ["title" => "发货", "click" => "newIframe('发货单详情','" . root . "control/adIndex.html?cla=saleSendOrder&fun=edit&orderId=" . $array['id'] . "')"],
            ];
            if ($array['state'] != '草稿') {
                unset($dominate['edit']);
            }
            if ($array['state'] != '已确认') {
                unset($dominate['backCar']);
            }
            if ($array['isClose'] == 1) {
                $array['state'] = '已完成';
            }
            $closeSign  = $array['isClose'] ? "<span class='no-choose'></span>" : '';//关闭单据颜色显示标志
            $liButton[] = $this->dominate($dominate) . $closeSign;
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case "companyName":
                        $kehu  = query('kehu', "khid = '$array[khid]'", "companyName");
                        $row[] = $kehu['companyName'];
                        break;
                    case "tags":
                        $tags  = orderTagClass::getTagName($array['id']);
                        $row[] = $tags;
                        break;
                    case "manager":
                        $row[] = self::findStaff($array['manager']);
                        break;
                    case "num":
                    case "send_num":
                    case "refund_num":
                        $row[] = self::lostZero($array[$key], 'numPrecision');
                        break;
                    case "residue":
                        $row[] = self::formattingFigure($array['num'] - $array['send_num'] + $array['refund_num'], 'numPrecision');
                        break;
                    case "completion_rate":
                        $row[] = ($array['completion_rate'] * 100) . '%';
                        break;
                    case "deliveryDate":
                        //判断是否超期
                        $schedule_show = 0;
                        if (strtotime($this->date) > strtotime($array['deliveryDate']) && !$array['deliver_on_schedule'] && $array['deliveryDate']) {
                            $schedule_show = 1;
                        }
                        $row[] = self::textTips($array['deliveryDate'], $schedule_show);
                        break;
                    case "money":
                        $row[] = self::lostZero($array['money'], 'amount');
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        $numTotal = find([
            'table'  => self::table,
            'single' => $where,
            'field'  => "ifnull(sum(num),0) as num,ifnull(sum(send_num),0) as send_num,ifnull(sum(refund_num),0) as refund_num,ifnull(sum(money),0) as money",
        ]);
        $total    = [
            'num'        => self::lostZero($numTotal['num'], 'numPrecision'),
            'send_num'   => self::lostZero($numTotal['send_num'], 'numPrecision'),
            'refund_num' => self::lostZero($numTotal['refund_num'], 'numPrecision'),
            'residue'    => self::formattingFigure($numTotal['num'] - $numTotal['send_num'] + $numTotal['refund_num'], 'numPrecision'),
            'money'      => self::lostZero($numTotal['money']),
        ];
        //生成页面
        $li = $this->li([
            "body"        => $body,
            "install"     => $installSearch,
            "button"      => ["html" => $liButton],
            "orderBySign" => $orderBy,
            "page"        => $page['para'],
            "total"       => $total,
        ]);
        //返回
        $json['html'] =
            "<form name='listForm'>" .
            $li .
            "</form>" .
            machiningOrderClass::closeJs() .
            $page['button'] .
            clear;
        return json_encode($json, 320);
    }

    /**
     * 导出
     */
    public function exportData()
    {
        if (!$this->power(self::page, 'edit')) {
            $_SESSION['warn'] = '你还没有导出的权限';
        } else {
            $tr     = [];
            $sql    = $_SESSION[self::page]['sql'];
            $title  = ["单据编号", "单据日期", "客户", "销售员", "收货人", "收货电话", "收货地址", "交货方式", "结算方式", "交货日期", "备注", '产品编码', '产品名称', '规格型号', '单位', '数量', '不含税单价(' . static::$unit . ')', '未税金额(' . static::$unit . ')', '税率', '税额(' . static::$unit . ')', '价税合计(' . static::$unit . ')', '客户料号', '客户品名', '产品备注'];
            $result = sqlFind($sql);
            if (is_array($result)) {
                foreach ($result as $array) {
                    $kehu     = query('kehu', "khid = '$array[khid]'");
                    $main     = [
                        $array['orderNo'],
                        $array['recordDate'],
                        $kehu['companyName'],
                        self::findStaff($array['manager']),
                        $array['contactName'],
                        $array['contactTel'],
                        $array['address'],
                        self::deliveryMethod[$array['delivery_method']],
                        $array['settlementType'] . ($array['settlementType'] == '月结' ? '-' . $array['settlementDay'] . '天' : ''),
                        self::null($array['deliveryDate']),
                        $array['text'],
                    ];
                    $resultMx = find(['table' => self::tableMx, 'where' => "orderId = '$array[id]' order by list"]);
                    foreach ($resultMx['array'] as $item) {
                        $material = query('material', " id = '$item[materialId]'");
                        $tr[]     = array_merge($main, [
                            $material['code'],
                            $material['name'],
                            $material['model'],
                            $item['unit'],
                            self::lostZero($item['num'], 'numPrecision'),
                            self::lostZero($item['price'], 'pricePrecision'),
                            self::formattingFigure($item['money'] - $item['taxMoney'], 'amount'),
                            ($item['rate'] * 100) . '%',
                            self::lostZero($item['taxMoney'], 'amount'),
                            self::lostZero($item['money'], 'amount'),
                            $item['khMaterialCode'],
                            $item['khMaterialName'],
                            $item['text'],
                        ]);
                    }
                }
            }
            $text = $this->control['name'] . "导出了" . self::title;
            $this->logText(["type" => self::page, "text" => $text]);
            $this->excelOut($title, $tr, self::title . ".xlsx");
        }
        header("Location:" . getenv("HTTP_REFERER"));
        exit(0);
    }

    public function exportData1()
    {
        $templateId = $this->get('templateId');
        $checkedId  = $this->get('checkedId') ? explode(',', $this->get('checkedId')) : [];
        if (!$this->power(self::page, 'edit')) {
            $_SESSION['warn'] = '你还没有导出的权限';
        } else {
            $data = [];
            /***********标题**********/
            $title        = [];
            $tempFieldAll = importTemplateClass::templateField(self::page, 'exportFieldInit', id: $templateId);
            foreach ($tempFieldAll as $array) {
                if ($array['display']) {
                    $title[] = $array['aliasName'];
                }
            }
            //判断是否选中导出
            if (!self::is_null_array($checkedId)) {
                $result = find(array(
                    "table" => self::table,
                    "where" => "id in ('" . implode("','", $checkedId) . "') order by recordDate desc,orderNo desc",
                ))['array'];
            } else {
                $sql    = $_SESSION[self::page]['sql'];
                $result = sqlFind($sql);
            }
            //导出数据生成
            foreach ($result as $array) {
                $column   = [];
                $kehu     = query('kehu', "khid = '$array[khid]'");
                $resultMx = find(['table' => self::tableMx, 'where' => "orderId = '$array[id]' order by list"]);
                foreach ($resultMx['array'] as $item) {
                    $material = query('material', " id = '$item[materialId]'");
                    foreach ($tempFieldAll as $templateField) {
                        if ($templateField['display']) {
                            $column[] = match ($templateField['columnName']) {
                                '单据编号' => $array['orderNo'],
                                '单据日期' => $array['recordDate'],
                                '客户' => $kehu['companyName'],
                                '销售员' => self::findStaff($array['manager']),
                                '收货人' => $array['contactName'],
                                '收货电话' => $array['contactTel'],
                                '收货地址' => $array['address'],
                                '交货方式' => self::deliveryMethod[$array['delivery_method']],
                                '结算方式' => $array['settlementType'] . ($array['settlementType'] == '月结' ? '-' . $array['settlementDay'] . '天' : ''),
                                '交货日期' => self::null($array['deliveryDate']),
                                '备注' => $array['text'],
                                '产品编码' => $material['code'],
                                '产品名称' => $material['name'],
                                '规格型号' => $material['model'],
                                '单位' => $item['unit'],
                                '数量' => self::lostZero($item['num'], 'numPrecision'),
                                '不含税单价(' . static::$unit . ')' => self::lostZero($item['price'], 'pricePrecision'),
                                '未税金额(' . static::$unit . ')' => self::formattingFigure($item['money'] - $item['taxMoney'], 'amount'),
                                '税率' => ($item['rate'] * 100) . '%',
                                '税额(' . static::$unit . ')' => self::lostZero($item['taxMoney'], 'amount'),
                                '价税合计(' . static::$unit . ')' => self::lostZero($item['money'], 'amount'),
                                '客户料号' => $item['khMaterialCode'],
                                '客户品名' => $item['khMaterialName'],
                                '产品备注' => $item['text'],
                                default => '',
                            };
                        }
                    }
                    $data[] = $column;
                }
            }
            $text = $this->control['name'] . "导出了" . self::title;
            $this->logText(["type" => self::page, "text" => $text]);
            $this->excelOut($title, $data, self::title . ".xlsx");
            exit(0);
        }
        header("Location:" . getenv("HTTP_REFERER"));
    }

    /**
     * 导出模板字段初始化
     * @return array[]
     */
    public function exportFieldInit($classify = ''): array
    {
        return match ($classify) {
            default => [
                [
                    'columnName' => '单据编号',
                ],
                [
                    'columnName' => '单据日期',
                ],
                [
                    'columnName' => '客户',
                ],
                [
                    'columnName' => '销售员',
                ],
                [
                    'columnName' => '收货人',
                ],
                [
                    'columnName' => '收货电话',
                ],
                [
                    'columnName' => '收货地址',
                ],
                [
                    'columnName' => '交货方式',
                ],
                [
                    'columnName' => '结算方式',
                ],
                [
                    'columnName' => '交货日期',
                ],
                [
                    'columnName' => '备注',
                ],
                [
                    'columnName' => '产品编码',
                ],
                [
                    'columnName' => '产品名称',
                ],
                [
                    'columnName' => '规格型号',
                ],
                [
                    'columnName' => '单位',
                ],
                [
                    'columnName' => '数量',
                ],
                [
                    'columnName' => '不含税单价(' . static::$unit . ')',
                ],
                [
                    'columnName' => '未税金额(' . static::$unit . ')',
                ],
                [
                    'columnName' => '税率',
                ],
                [
                    'columnName' => '税额(' . static::$unit . ')',
                ],
                [
                    'columnName' => '价税合计(' . static::$unit . ')',
                ],
                [
                    'columnName' => '客户料号',
                ],
                [
                    'columnName' => '客户品名',
                ],
                [
                    'columnName' => '产品备注',
                ],
            ]
        };
    }

    /**
     * 下载模板
     */
    public function downloadModel()
    {
        $templateId = $this->get('templateId');
        if (!$this->power(self::page, 'import')) {
            $_SESSION['warn'] = '你还没有导入的权限';
        } else {
            $exampleData[] = [
                '2023-02-24', 'C0001', 'A客户', 'S0001', 'A客户的销售合同', 'YM202211030001', '张三', '自提', '月结', 30, '2023-03-24', '李四', '13000000000', '重庆市', '样例数据', '否', 'CP0001', 'A产品', '包', 100, 50, 5, '', '', '', '测试数据',
            ];

            $excel         = $this->excelHead();
            $fileName      = self::title . '导入模板-' . importTemplateClass::getName($templateId) . '.xlsx';
            $filePath      = $excel->fileName($fileName, 'sheet1');
            $format        = new \Vtiful\Kernel\Format($filePath->getHandle());
            $templateField = importTemplateClass::templateField(self::page, 'importFieldInit', id: $templateId);
            $index         = 0;
            foreach ($templateField as $k => $array) {
                if ($array['display']) {
                    $backgroundStyle = null;
                    if (importTemplateClass::getIsMustValue($this->importFieldInit(), $array['columnName'])) {
                        //必填项判断
                        $backgroundStyle = $format->background(
                            0xFFC04B
                        )->toResource();
                    }
                    $filePath->insertText(0, $index, $array['aliasName'], '', $backgroundStyle);
                    foreach ($exampleData as $y => $example) {
                        $filePath->insertText($y + 1, $index, $example[$k] ?? '');
                    }
                    $index++;
                }
            }

            $text = $this->control['name'] . "下载了" . self::title . "导入模板";
            $this->logText(["type" => self::page, "text" => $text]);
            $this->excelOutPut($filePath, $fileName);
            exit(0);
        }
        header("Location:" . getenv("HTTP_REFERER"));
    }

    /*数据导入*/
    public function importData()
    {
        $templateId = $this->post('templateId');
        if (!$this->power(self::page, 'import')) {
            $json['warn'] = '你还没有导入的权限';
        } else {
            $fomatArray = [];//导入数据格式同一为TYPE_STRING
            foreach ($this->importFieldInit() as $value) {
                $fomatArray[] = \Vtiful\Kernel\Excel::TYPE_STRING;
            }
            $data                  = $this->importHead(format: $fomatArray);
            $x                     = 0;
            $text                  = '';
            $saleOrder             = [];
            $delivery_method_array = ['配送' => 2, '自提' => 1];
            $headArray             = [];
            $row_list              = 0;
            foreach ($data as $i => $row) {
                $row_list++;
                if ($i == 0) {
                    $templateField = importTemplateClass::templateField(self::page, 'importFieldInit', id: $templateId);
                    $headArray     = importTemplateClass::combinHead($templateField, $row);
                }
                if ($i > 0) {
                    $rowData = formSubArray($row);
                    //只接收模板中选中的字段的值
                    $cell = [];
                    foreach ($headArray as $index => $headName) {
                        $cell[$headName] = $rowData[$index] ?? '';
                    }
                    //初始化未被模板需要的字段的值
                    foreach ($this->importFieldInit() as $value) {
                        $cell[$value['columnName']] = $cell[$value['columnName']] ?? '';
                    }
                    if (!empty($cell['单据日期'])) {
                        $saleOrder = [];
                        if ($cell['客户编码']) {
                            $kehu = query('kehu', "coid = '" . self::$coid . "' and orderNo = '$cell[客户编码]'");
                        } else {
                            $kehu = query('kehu', "coid = '" . self::$coid . "' and companyName = '$cell[客户名称]'");
                        }
                        $saleContract = query('sales_contract', "orderNo = '$cell[3]'");
                        $saleMan      = query('staff', "orderNo = '$cell[5]'");
                        $field        = [
                            'type'            => '销货',
                            'text'            => $cell['单据备注'],
                            'contractId'      => $saleContract['id'],
                            'khid'            => $kehu['khid'],
                            'recordDate'      => self::importDateFormat($cell['单据日期']),
                            'deliveryDate'    => self::importDateFormat($cell['交货日期']),
                            'contactName'     => $cell['收货人'],
                            'contactTel'      => $cell['收货电话'],
                            'address'         => $cell['收货地址'],
                            'isTax'           => $cell['是否含税'] == '是' ? 1 : 0,
                            'settlementType'  => $cell['结算方式'],
                            'settlementDay'   => $cell['结算周期'],
                            'delivery_method' => $delivery_method_array[$cell['交货方式']],
                            'manager'         => $saleMan['stid'],
                        ];
                        $annotation   = [
                            'khid'            => '客户',
                            'recordDate'      => '单据日期',
                            'delivery_method' => '交货方式',
                            'settlementType'  => '结算方式',
                        ];
                        $rules        = [
                            'khid'            => 'required',
                            'recordDate'      => 'required|date',
                            'delivery_method' => 'required',
                            'settlementType'  => 'required',
                        ];
                        // 校验是否符合规则
                        $vt     = new \verify();
                        $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
                        if ($result === false) {
                            $text .= "\n第【{$row_list}】行，" . $vt->getErrs()[0];
                        } elseif ($field['settlementType'] == '月结' && empty($field['settlementDay'])) {
                            $text .= "\n第【{$row_list}】行，请填写结算周期";
                        } else {
                            $pass = true;
                            //判断客户信用额度
                            $setting = optionSettingClass::getSetting('销售');
                            if (isset($setting['creditCtrl']['option']) && $setting['creditCtrl']['option'] && $setting['creditCtrl']['way'] == '保存') {
                                $kehu    = query('kehu', "khid = '$field[khid]'");
                                $balance = self::clientBalance($field['khid']);
                                if ($kehu['credits'] < $balance) {
                                    $text .= "\n第【{$row_list}】行，此客户信用额度不足";
                                    $pass = false;
                                }
                            }
                            if ($pass) {
                                // 新增
                                $userNo = codeTemplateClass::generateCode(self::page, [
                                    'prefix' => 'XSDD' . date('Ymd', strtotime($field['recordDate'])),
                                    'table'  => self::table,
                                    'field'  => 'orderNo',
                                    'where'  => " and coid = '" . self::$coid . "'",
                                ], $field);
                                $field  = array_merge($field, [
                                    'id'      => suiji(),
                                    'orderNo' => $userNo,
                                    'state'   => '草稿',
                                    'coid'    => self::$coid,
                                    'stid'    => $this->control['stid'],
                                ]);
                                $warn   = static::insert([
                                    "table" => self::table,
                                    "field" => $field,
                                ]);
                                if (in_array($warn, ["新增成功", "更新成功"])) {
                                    $saleOrder = $field;
                                } else {
                                    $text .= "\n第【{$row_list}】行，插入主数据失败，" . $warn;

                                }
                            }
                        }

                    }
                    if (isset($saleOrder['id']) && !empty($saleOrder['id'])) {
                        if ($cell['产品编码']) {
                            $material = query('material', "coid = '" . self::$coid . "' and code = '$cell[产品编码]'");
                        } else {
                            $material = query('material', "coid = '" . self::$coid . "' and name = '$cell[产品名称]'");
                        }
                        if (empty($material['id'])) {
                            $text .= "\n第【{$row_list}】行，未通过编码找到此物料";
                        } elseif (!in_array($cell['单位'], machiningOrderClass::unitOption($material['id']))) {
                            $text .= "\n第【{$row_list}】行，单位【{$cell['单位']}】不在此物料的可选单位范围内";
                        } else {
                            $cell['税率'] = ($cell['税率'] ?: 0) / 100;
                            //明细

                            if (!empty($cell['价税合计'])) {
                                $result     = self::priceAndMoney($cell['价税合计'], $cell['税率'], $saleOrder['isTax'], $cell['数量'] ?: 0);
                                $cell['单价'] = $result['price'];
                            }
                            $result  = self::isTax($cell['数量'] ?: 0, $cell['单价'] ?: 0, $cell['税率'], $saleOrder['isTax']);
                            $mxField = [
                                'id'              => suiji(),
                                'orderId'         => $saleOrder['id'],
                                'coid'            => self::$coid,
                                'materialId'      => $material['id'],
                                'unit'            => $cell['单位'],
                                'num'             => $cell['数量'],
                                'price'           => $cell['单价'],
                                'taxMoney'        => $result['taxMoney'],//税额
                                'moneyWithOutTax' => $result['money'],//不含税金额
                                'money'           => $cell['价税合计'] ?: $result['moneyWithTax'],//价税合计
                                'rate'            => $cell['税率'],
                                'text'            => $cell['备注'],
                                'khMaterialCode'  => $cell['客户料号'],
                                'khMaterialName'  => $cell['客户品名'],
                            ];
                            $warn    = static::insert([
                                "table" => self::tableMx,
                                "field" => $mxField,
                            ]);
                            if (in_array($warn, ["新增成功", "更新成功"])) {
                                $text  .= "\n第【{$row_list}】行，导入成功";
                                $total = find([
                                    'table'  => self::tableMx,
                                    'single' => "orderId = '$saleOrder[id]'",
                                    'field'  => "ifnull(sum(num),0) as num,ifnull(sum(money),0) as money",
                                ]);
                                update([
                                    'table' => self::table,
                                    'field' => ['num' => $total['num'], 'money' => $total['money']],
                                    'where' => "id = '$saleOrder[id]'",
                                ]);
                                $x++;
                            } else {
                                $text .= "\n第【{$row_list}】行，导入失败：插入数据库失败，" . $warn;
                            }
                        }
                    } else {
                        $text .= "\n第【{$row_list}】行，未找到单据";
                    }
                }
            }
            $total        = count($data) - 1;
            $json['data'] = [
                'text'  => $text,
                'title' => "您导入了{$total}条数据，成功{$x}条，失败" . ($total - $x) . "条",
            ];
            $text         = $this->control['name'] . '导入了文件：' . $_FILES['file']['name'] . '：' . $text;
            $this->logText(["type" => self::page, "text" => $text]);
            $json['warn'] = 2;
        }
        return json_encode($json, 320);
    }

    /**
     * 编辑页
     *
     * @return string
     */
    public function edit(): string
    {
        $id   = $this->get('id') ?: suiji();
        $info = query(self::table, " id = '" . $id . "' ");

        $button[] = [
            "name"  => "保存",
            "type"  => "点击事件",
            "title" => "保存为草稿",
            'fun'   => "subForm('" . self::page . "EditForm','" . root . "control/adIndex.html?cla=" . self::page . "&fun=editEdit')",
        ];
//        $button[] = [
//            "name"  => "保存并提交",
//            "type"  => "点击事件",
//            "title" => "保存",
//            'fun'   => "subForm('" . self::page . "EditForm','" . root . "control/adIndex.html?cla=" . self::page . "&fun=saveAndCommit')",
//            'style' => 'li-btn-blue-bg',
//        ];
        $tr[]     = ['', '产品编码', '产品名称', '规格型号', must.'单位', must.'桶装数量', must.'气瓶数量', must.'单价(' . static::$unit . ')', '备注'];
        $result   = find(['table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list"]);
        $totalArr = ['total_num' => 0, 'total_row_money' => 0, 'total_tax_money' => 0, 'total_money' => 0];
        foreach ($result['array'] as $k => $array) {
            $material                    = query('material', " id = '$array[materialId]'");
            $money                       = self::formattingFigure($array['money'] - $array['taxMoney'], 'amount');
            $tr[]                        = [
                componentClass::tablePperation($k + 1, "delTableRow(this);calculateTotal()") .
                hidden(['name' => 'mxId[]', 'value' => $array['id']]) .
                hidden(['name' => 'materialId[]', 'value' => $array['materialId']]) .
                hidden(['name' => 'contract_detail_id[]', 'value' => $array['contract_detail_id']]),
                $material['code'],
                $material['name'],
                $material['model'],
                select(['name' => 'unit[]', 'data' => ['unit' => $array['unit']], 'change' => 'unitChange', 'option' => machiningOrderClass::unitOption($material['id']), 'title' => '单位', 'value' => $array['unit']]),
                text(['name' => 'num[]', 'type' => 'text', 'blur' => 'countMoney', 'other' => self::digitalFiltering('numPrecision'), 'value' => $array['num'] ? self::lostZero($array['num'], 'numPrecision') : '']),
                text(['name' => 'weight[]', 'type' => 'text', 'blur' => 'countMoney', 'other' => self::digitalFiltering('numPrecision'), 'value' => $array['weight'] ? self::lostZero($array['weight'], 'numPrecision') : '']),
                text(['name' => 'price[]', 'type' => 'text', 'blur' => 'countMoney', 'other' => self::digitalFiltering('pricePrecision'), 'value' => $array['price'] ? self::lostZero($array['price'], 'pricePrecision') : '']),
                text(['name' => 'mxText[]', 'class' => 'text textPrice', 'value' => $array['text']]),
            ];
            $totalArr['total_num']       += $array['num'];
            $totalArr['total_row_money'] += $money;
            $totalArr['total_tax_money'] += $array['taxMoney'];
            $totalArr['total_money']     += $array['money'];
        }
        $total = [];
        $table      = $this->listTable(['tr' => $tr, 'end' => true, 'total' => $total]);
        $mxButton   = <<<efo
                    <span class="smallButton" onclick="layer('{$this->get('cla')}','addContract',$('form[name=saleOrderEditForm]').serialize())">选择合同明细</span>
                    <span class="smallButton" onclick="layer('{$this->get('cla')}','addMx',$('form[name=saleOrderEditForm]').serialize())">选择产品</span>
efo;
        $kehu       = query('kehu', "khid = '$info[khid]'");
        $settlement = array_merge(para('supplierSettlement', '，'), ['月结']);
        $userNo     = $info['orderNo'] ?: codeTemplateClass::generateCode(self::page, [
            'prefix' => 'XSDD' . date('Ymd'),
            'table'  => self::table,
            'field'  => 'orderNo',
            'where'  => " and coid = '" . self::$coid . "'",
        ], $info);
        //表单
        $data['button'] = $this->tableShowButton($button);
        $body           = $this->edit4([
            '基本信息' => [
                [
                    must . "单据编号：" => text(["name" => "orderNo", 'class' => 'text', "value" => $userNo]),
                    must . "单据日期：" => text(["name" => "recordDate", 'class' => 'text', 'laydate' => [], "value" => $info['recordDate'] ?: $this->date]),
                    must . "客户："   =>
                        componentClass::selectText([
                            'name'   => 'khid',
                            'value'  => $info['khid'],
                            'title'  => $kehu['companyName'],
                            'cla'    => self::page,
                            'fun'    => 'getClient',
                            'change' => 'getContract',
                        ]) .
                        "<img class='cursor' title='新增' onclick=\"newIframe('我的客户','" . root . "control/adIndex.html?cla=client&fun=edit')\" src='".root."img/control/list_add.svg'>".
                        "<img class='cursor' title='客户详情' onclick=\"jumpPage('" . root . "control/adIndex.html?cla=client&fun=detail')\" src='".root."img/control/detail.svg'>",
                    "合同："          =>
                        "<div id='contract' class='full'>" .
                        selectMultiple([
                            "name"     => "contractId",
                            "value"    => $info['contractId'],
                            'table'    => "sales_contract",
                            'where'    => "clientId = '$info[khid]' and state = '已通过'",
                            'sqlId'    => 'id',
                            'sqlField' => 'name',
                            'title'    => '请选择',
                        ]) .
                        "</div>",
                ],
                [
                    "销售员："         =>
                        "<div id='manager' class='full'>" .
                        selectMultiple([
                            "name"     => "manager",
                            "value"    => $info['manager'],
                            'table'    => "staff",
                            'where'    => " 1=1 ",
                            'sqlId'    => 'stid',
                            'sqlField' => 'name',
                            'title'    => '请选择',
                        ]) .
                        "</div>",
                    must . "交货方式：" => radio(['name' => 'delivery_method', 'checked' => $info['delivery_method'] ?: '1', 'value' => self::deliveryMethod]),
                    must . "结算方式：" => radio(['name' => 'settlementType', 'change' => 'settlementDayDefault', 'checked' => $info['settlementType'] ?: $settlement[0], 'value' => $settlement]) .
                        "&nbsp;" .
                        text(['name' => 'settlementDay', 'type' => 'number', 'value' => $info['settlementDay'] ?: '', 'title' => '结算周期']),
                ],
                [
                    must . "交货日期：" => text(["name" => "deliveryDate", 'class' => 'text', 'laydate' => [], "value" => $info['deliveryDate']]),
                    "收货人："         => text(["name" => "contactName", 'class' => 'text', "value" => $info['contactName']]) .
                        "<span class='del-row-button m-l-5' onclick=\"layer('saleOrder','receiver',{contractId:$('[name=contractId]').val(),khid:$('[name=khid]').val()})\">选择</span>",
                    "收货电话："        => text(["name" => "contactTel", 'class' => 'text', "value" => $info['contactTel']]),
                    "收货地址："        => text(["name" => "address", 'class' => 'text', "value" => $info['address']]),
                ],
                [
                    "驾驶员："         =>
                        "<div class='full'>" .
                        selectMultiple([
                            "name"     => "delivery_name",
                            "value"    => $info['delivery_name'],
                            'table'    => "staff",
                            'where'    => " 1=1 ",
                            'sqlId'    => 'stid',
                            'sqlField' => 'name',
                            'title'    => '请选择',
                        ]) .
                        "</div>",
                    "押运员："         =>
                        "<div class='full'>" .
                        selectMultiple([
                            "name"     => "delivery_manage",
                            "value"    => $info['delivery_manage'],
                            'table'    => "staff",
                            'where'    => " 1=1 ",
                            'sqlId'    => 'stid',
                            'sqlField' => 'name',
                            'title'    => '请选择',
                        ]) .
                        "</div>",
                    "选择车辆："         =>
                        "<div class='full'>" .
                        selectMultiple([
                            "name"     => "car_id",
                            "value"    => $info['car_id'],
                            'table'    => "logistics_car",
                            'where'    => " 1=1 and state='正常' and coid='".self::$coid."'",
                            "field"    => "id,CONCAT(shortName, '',carNo) AS car_name",
                            'sqlId'    => 'id',
                            'sqlField' => 'car_name',
                            'title'    => '请选择',
                        ]) .
                        "</div>",
                    "运费："        => text(["name" => "freight", 'class' => 'text', "value" => $info['freight']]),
                ],
                [
                    "备注：" => textarea(["name" => "text", 'class' => 'text', "value" => $info['text']]),
                ],
            ]
        ]);
        $body           .= $this->editList([
            'id'     => 'materialTable',
            'title'  => '订单明细',
            'button' => $mxButton,
            'html'   => $table,
        ]);
        $body           .= $this->editBlock([
            '附件' => fileUploadClass::addFileComponent($id, '销售单', self::page, self::page . 'EditForm')
        ]);

        $data['html'] = $this->pageEdit([
            "html"   => $body,
            'hidden' => hidden(['name' => 'id', 'value' => $id]),
        ]);
        $cla          = self::page;
        $data['html'] .= <<<efo
<script>
//跳转详情
function jumpPage(url){
    let khid = $("[name='khid']").val();
    if(!khid){
        warn('请选择客户','error')
        return
    }
    newIframe('客户详情',url+'&id='+khid)
}
//根据客户获取合同
function getContract(){
    let khid = $("[name='khid']").val();
    let val = $("[name='contractId']").val();
    $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=getContract',{khid:khid,value:val},function(res) {
          $("#contract").html(res.html);
          $("#manager").html(res.manager);
          $("[name='settlementDay']").val();
          $("[name='settlementType'][value='"+res.settleType+"']").attr('checked',true)
    },'json');
}
function addRow(){
    var type = arguments[0]
    if(type === 'contract'){
        $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addContractEdit',$("form[name='contractForm']").serialize(),function(res) {
            $("#materialTable tbody").append(res.html);
            resetNumber($("#materialTable tbody"))
            calculateTotal()
        },'json');
    }else{
        $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addMxEdit',$("form[name='mxForm']").serialize(),function(res) {
            $("#materialTable tbody").append(res.html);
            resetNumber($("#materialTable tbody"))
            calculateTotal()
        },'json');
    }
}
function chooseRec(){
     $('#saleOrderReceiver').hide();
      $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=getReceiver',$("form[name='recForm']").serialize(),function(res) {
          $("[name='contactName']").val(res.data.name);
          $("[name='contactTel']").val(res.data.tel);
          $("[name='address']").val(res.data.address);
    },'json');
}
</script>

efo. $this->editJs();
        //返回
        return $this->tab($data);
    }


    public function editJs(): string
    {
        return <<<eof
<script>
//根据单位转换所需数量和库存
function unitChange(e){
    let unit = e.value;
    if (!unit){
        msg('请选择单位')
        return '';
    }
    let oldUnit = $(e).data('unit');
    $(e).data('unit',unit);
    let num = $(e).parent().parent().find("[name='num[]']").val();
    let id = $(e).parent().parent().find("[name='materialId[]']").val();
    $.post(root+'control/adIndex.html?cla=machiningInOrder&fun=unitChange',{unit:unit,oldUnit:oldUnit,num:num,id:id},function(res) {
        if (res.warn==2){
            $(e).parent().parent().find("[name='num[]']").val(res.num);
            countMoney(e);
            $(e).parent().parent().find(".inventory").html(res.inventoryNum);
        }else{
            msg(res.warn);
        }
    },'json');
}

//通过单价计算金额，税额等
function countMoney(e){
    let trObj = $(e).parent().parent();
    countProcess(trObj)
}
function countProcess(trObj){
    let price = trObj.find("[name='price[]']").val();
    let num = trObj.find("[name='num[]']").val();
    let rate = trObj.find("[name='rate[]']").val();
    rate = Number(rate)/100;
    let money;
    let taxMoney,moneyWithTax;
    if($("[name='isTax']").prop("checked")){
       //含税单价
       taxMoney = (Number(price)*Number(num)/(1+rate)*rate).toFixed(amountPrecision);
       moneyWithTax = (Number(price)*Number(num)).toFixed(amountPrecision);
       money = Number(moneyWithTax-taxMoney).toFixed(amountPrecision)
    }else{
       //未含税单价
        taxMoney = (Number(price)*Number(num)*rate).toFixed(amountPrecision);
        moneyWithTax = (Number(price)*Number(num)*(1+rate)).toFixed(amountPrecision);
        money = (Number(price)*Number(num)).toFixed(amountPrecision);
    }
    trObj.find(".rowMoney").html(money)
    trObj.find(".taxMoney").html(taxMoney)
    trObj.find("[name='moneyWithTax[]']").val(moneyWithTax)
    calculateTotal()
}


//通过价税合计计算单价
function calculatePrice(e){
    let trObj = $(e).parent().parent();
    let moneyWithTax = Number(e.value);//价税合计
    let num = Number(trObj.find("[name='num[]']").val());
    let rate = Number(trObj.find("[name='rate[]']").val());
    if(num > 0){
        rate = Number(rate)/100;
        let taxMoney,price,money;
        taxMoney = (moneyWithTax/(1+rate)*rate).toFixed(amountPrecision);//税额
        if($("[name='isTax']").is(":checked")){
           //含税
           price = moneyWithTax/num;
           money = moneyWithTax-taxMoney;
        }else{
           //未含税
            price = (moneyWithTax-taxMoney)/num;
            money = moneyWithTax-taxMoney;
        }
        trObj.find(".rowMoney").html(money.toFixed(amountPrecision))
        trObj.find(".taxMoney").html(taxMoney);
        trObj.find("[name='price[]']").val(price.toFixed(publicSettings.pricePrecision.num))
    }
    calculateTotal()
}
//计算总金额，总税额
function calculateTotal(table=''){
    table = table ? table : $('.editList')
    let num = 0,
    rowMoney = 0,
    taxMoney = 0,
    money = 0;
    table.find("[name='num[]']").each(function(index){
        if($(this).val()){
          num+=Number($(this).val());
        }
        var rowMoneyText = table.find(".rowMoney").eq(index).text()
        if(rowMoneyText){
            rowMoney+=Number(rowMoneyText);
        }
        var taxMoneyText = table.find(".taxMoney").eq(index).text()
        if(taxMoneyText){
            taxMoney+=Number(taxMoneyText);
        }
        var moneyValue = table.find("[name='moneyWithTax[]']").eq(index).val()
        if(moneyValue){
            money+=Number(moneyValue);
        }
    })
    $("#total_num").text(num.toFixed(publicSettings.numPrecision.num));
    $("#total_row_money").text(rowMoney.toFixed(amountPrecision));
    $("#total_tax_money").text(taxMoney.toFixed(amountPrecision));
    $("#total_money").text(money.toFixed(amountPrecision));
}

//切换含税不含税复选框
function taxChange(e){
    $("#materialTable tbody tr").each(function() {
       countProcess($(this))
    })
}
</script>
eof;
    }

    /**
     * 选择税率
     *
     * @param string $obj
     * @return string
     */
    public static function chooseRate(string $obj = ''): string
    {
        $obj    = $obj ?: 'rate';
        $result = explode('，', para('taxRate'));
        $li     = '';
        if (is_array($result)) {
            foreach ($result as $array) {
                $li .= "<li data-id='$array'>{$array}</li>";
            }
        }
        if (empty($li)) {
            $li = "<li>未找到税率</li>";
        }
        return <<<EOT
        <span class='del-row-button' id='chooseRate'>批量</span><div class='rateBlock' style="margin-top: 0;"><ul>$li</ul></div>
        <script>
         //点击非下拉区域隐藏
        $(document).bind('click', function (e) {
            let target = $(".rateBlock");
            let obj = $(".rate");
            if(!target.is(e.target) && target.has(e.target).length ===0 && !obj.is(e.target) && obj.has(e.target).length ===0){
              target.hide();
            }
        });
        $("#chooseRate").on('click',function() {
           $(".rateBlock").show();
        })
          $(".rate .rateBlock li").on('click',function() {
            let id = $(this).data('id');
            $("select[name='{$obj}[]']").each(function() {
              let obj = $(this);
              obj.val(id);
                countMoney(this);
            });
           $(".rateBlock").hide();
        })
        </script>    
EOT;
    }


    /**
     * 根据价税合计计算单价和金额
     * @param $moneyWithTax
     * @param $rate
     * @param $isTax
     * @param $num
     * @return array
     */
    public static function priceAndMoney($moneyWithTax, $rate, $isTax, $num)
    {
        $taxMoney = ($moneyWithTax / (1 + $rate) * $rate);//税额
        if ($isTax) {
            //含税
            $price = $num > 0 ? $moneyWithTax / $num : 0;
        } else {
            //未含税
            $price = $num > 0 ? ($moneyWithTax - $taxMoney) / $num : 0;
        }
        $money = $moneyWithTax - $taxMoney;
        return ['price' => $price, 'money' => $money];
    }

    /**
     * 模糊查询客户
     *
     * @return bool|string
     */
    public function getClient(): bool|string
    {
        $val             = $this->post('keyword');//关键词
        $json['warn']    = 0;
        $json['data']    = [];
        $where           = empty($val) ? "1=1" : "(companyName like '%" . $val . "%' or orderNo like '%" . $val . "%')";
        $where           .= " and coid = '" . self::$coid . "' ";
        $page            = $this->page(array(
            'field' => " * ",
            "table" => 'kehu',
            "where" => $where,
            "order" => ' time asc ',
        ));
        $json['pageAll'] = $page['para']['pageAll'];

        foreach ($page['array'] as $val) {
            $json['data'][] = [
                'title'   => $val['companyName'],
                'orderNo' => $val['orderNo'],
                'id'      => $val['khid'],
                'companyNum'      => $val['companyNum'],
                'companyAddress'      => $val['companyAddress'],
                'companyBank'      => $val['companyBank'],
                'companyBankNum'      => $val['companyBankNum'],
            ];
        }
        $json['warn'] = 2;
        return json_encode($json, 320);
    }

    /**
     * 获取合同
     */
    public function getContract()
    {
        $khid               = $this->post('khid');
        $kehu               = query('kehu', "khid = '$khid'");
        $json['settleType'] = $kehu['settleType'];
        $json['html']       = selectMultiple(["name" => "contractId", 'table' => "sales_contract", 'where' => "clientId = '$khid' and state = '已通过' order by time desc", 'sqlId' => 'id', 'sqlField' => 'name', 'title' => '请选择']);
        $json['manager']    = selectMultiple(["name" => "manager", "value" => $kehu['manager'], 'table' => "staff", 'where' => " 1=1 ", 'sqlId' => 'stid', 'sqlField' => 'name', 'title' => '请选择']);
        return json_encode($json, 320);
    }

    public function editEdit()
    {
        //附件
        $fileIdArr             = $this->post('fileId');
        $id                    = $this->post('id') ?: self::getId();
        $mxIdArr               = $this->post('mxId') ?: [];
        $materialIdArr         = $this->post('materialId');
        $contract_detail_idArr = $this->post('contract_detail_id');
        $numArr                = $this->post('num');
        $weightArr                = $this->post('weight');
        $unitArr               = $this->post('unit');
        $priceArr              = $this->post('price');
        $mxTextArr             = $this->post('mxText');
        $taxRateArr            = $this->post('rate');
        $field                 = [
            'orderNo'         => $this->post('orderNo'),
            'type'            => '销货',
            'text'            => $this->post('text'),
            'contractId'      => $this->post('contractId'),
            'khid'            => $this->post('khid'),
            'recordDate'      => $this->post('recordDate'),
            'deliveryDate'    => $this->post('deliveryDate'),
            'contactName'     => $this->post('contactName'),
            'contactTel'      => $this->post('contactTel'),
            'address'         => $this->post('address'),
            'isTax'           => $this->post('isTax') ? 1 : 0,
            'settlementType'  => $this->post('settlementType'),
            'settlementDay'   => $this->post('settlementDay'),
            'delivery_method' => $this->post('delivery_method'),
            'delivery_name' => $this->post('delivery_name'),
            'manager'         => $this->post('manager'),
            'freight'         => $this->post('freight'),
            'car_id'          => $this->post('car_id'),
            'delivery_manage' => $this->post('delivery_manage'),
        ];
        $where                 = " id = '$id' ";
        $info                  = query(self::table, $where);
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有编辑" . self::title . "的权限";
        } elseif (!empty($info['id']) && $info['state'] == '已确认') {
            $json['warn'] = '此销售单已确认，不能修改';
        } else {
            $json['warn'] = '';

            if (empty($json['warn'])) {
                //$kehu = query('kehu', "khid = '$field[khid]'");
                $this->startTrans();
                $isPass = true;//事务通过标志
                if (!$info['id']) {
                    $field        = array_merge($field, [
                        'id'    => $id,
                        'state' => '草稿',
                        'coid'  => self::$coid,
                        'stid'  => $this->control['stid'],
                    ]);
                    $json['warn'] = static::insert(["table" => self::table, "field" => $field]);
                } else {
                    $json['warn'] = static::update([
                        "table" => self::table,
                        "field" => $field,
                        "where" => $where,
                    ]);
                }

                //添加或更新明细
                if (is_array($mxIdArr)) {
                    foreach ($mxIdArr as $k => $nid) {
                        $mx           = query(self::tableMx, "id = '$nid'");
                        $numArr[$k]   = self::formattingFigure($numArr[$k], 'numPrecision');
                        $priceArr[$k] = self::formattingFigure($priceArr[$k], 'pricePrecision');
                        //数据格式处理
                        $taxRateArr[$k] = floatval($taxRateArr[$k] ?? 0) / 100;//税率从百分比转为小数
                        $result         = self::isTax($numArr[$k], $priceArr[$k], $taxRateArr[$k], $field['isTax']);
                        if (!empty($mx['id'])) {
                            //更新
                            $warn = static::update([
                                "table" => self::tableMx,
                                "field" => [
                                    'contract_detail_id' => $contract_detail_idArr[$k],
                                    'materialId'         => $materialIdArr[$k],
                                    'unit'               => $unitArr[$k],
                                    'num'                => $numArr[$k],
                                    'weight'                => $weightArr[$k],
                                    'price'              => $priceArr[$k],
                                    'taxMoney'           => $result['taxMoney'],//税额
                                    'moneyWithOutTax'    => $result['money'],//不含税金额
                                    'money'              => 0,//价税合计
                                    'rate'               => $taxRateArr[$k],
                                    'text'               => $mxTextArr[$k],
                                    'khMaterialCode'     => 0,
                                    'khMaterialName'     => 0,
                                ],

                                "where" => " id = '$nid'",
                            ]);
                        } else {
                            //新增
                            $warn = static::insert([
                                "table" => self::tableMx,
                                "field" => [
                                    'id'                 => $nid,
                                    'orderId'            => $id,
                                    'coid'               => self::$coid,
                                    'contract_detail_id' => $contract_detail_idArr[$k],
                                    'materialId'         => $materialIdArr[$k],
                                    'unit'               => $unitArr[$k],
                                    'num'                => $numArr[$k],
                                    'weight'                => $weightArr[$k],
                                    'price'              => $priceArr[$k],
                                    'taxMoney'           => $result['taxMoney'],//税额
                                    'moneyWithOutTax'    => $result['money'],//不含税金额
                                    'money'              => 0,//价税合计
                                    'rate'               => $taxRateArr[$k],
                                    'text'               => $mxTextArr[$k],
                                    'khMaterialCode'     => 0,
                                    'khMaterialName'     => 0,
                                ],

                            ]);
                        }
                        if (!in_array($warn, ['新增成功', '更新成功'])) {
                            $isPass       = false;
                            $json['warn'] = $warn;
                            break;
                        }
                    }
                }
                //添加主表ID到附件表
                if (is_array($fileIdArr)) {
                    $warn = update([
                        'table' => 'file',
                        'field' => ['targetId' => $id],
                        'where' => " targetId = '' and id in ('" . implode("','", $fileIdArr) . "')",
                    ]);
                    if ($warn != '更新成功') {
                        $json['warn'] = $warn;
                        $isPass       = false;
                    }
                }
                if (in_array($json['warn'], ["新增成功", "更新成功"]) && $isPass) {
                    $this->commitTrans();
                    delete(['table' => self::tableMx, 'where' => " id not in ('" . implode("','", $mxIdArr) . "') and orderId = '$id'"]);
                    $total = find(['table' => self::tableMx, 'single' => "orderId = '$id'", 'field' => "ifnull(sum(num),0) as num,ifnull(sum(money),0) as money"]);
                    update(['table' => self::table, 'field' => ['num' => $total['num'], 'money' => $total['money']], 'where' => "id = '$id'"]);
                    if ($json['warn'] == '新增成功') {
                        self::insertOperateLog($id, self::title, "新建");
                    }
                    //添加日志
                    $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                    $text = $this->control['name'] . $type . "了" . self::title . " id：【" . $id . '】';
                    $this->logText(["type" => self::page, "text" => $text]);
                    //返回
                    $_SESSION['warn'] = $json['warn'];
                    $json['warn']     = 2;
                    $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $id;
                } else {
                    $this->rollback();
                }
            }
        }

        resp:
        return json_encode($json, 320);
    }

    /**
     * 客户应收余额
     *
     * @param $khid
     * @return float
     */
    public static function clientBalance($khid): float
    {
        $setting = optionSettingClass::getSetting('销售');
        $money   = find(['table' => 'record', 'where' => "typeId = '$khid' and coid = '" . self::$coid . "'", 'sum' => "money"]);//客户余额
        if ($setting['creditCtrl']['saleMoney']) {
            $money = 0;
        }
        //已订未出货
        if ($setting['creditCtrl']['bookingMoney']) {
            $all = find([
                'table' => "sale_send_order_detail as a join sale_send_order as b on a.orderId = b.id join inventory_detail as c on c.sourceId = a.id join inventory as d on c.orderId = d.id",
                'where' => "b.state = '已确认' and b.khid = '$khid' and a.coid = '" . self::$coid . "' and d.state !='已出库'",
                'field' => "c.*",
            ]);
            foreach ($all['array'] as $array) {
                $material = query('material', "id = '$array[materialId]'");
                $num      = machiningOrderClass::material_num_change($array['materialId'], $array['unit'], $material['unit'], $array['orderNum'] - $array['num']);
                $money    += self::formattingFigure((1 + $array['rate']) * $array['price'] * $num, 'amount');
            }
        }
        return $money;
    }

    /**
     * 获取收货人
     */
    public function getReceiver(): bool|string
    {
        /*if ($this->post('contractId')) {
            $info = query('sales_contract_address', "id = '" . $this->post('peopleId') . "'");
        } else {
        }*/
        $info = query('kehu_staff', "id = '" . $this->post('peopleId') . "'");
        $json['data'] = $info;
        return json_encode($json, 320);
    }

    /**
     * 选择收货人
     *
     * @return bool|string
     */
    public function receiver()
    {
        $html   =
            text(["name" => "contactName", "title" => "收货人"]) .
            text(["name" => "contactTel", "title" => "收货电话"]) .
            text(["name" => "address", "title" => "收货地址"]) .
            hidden(['name' => 'contractId', 'value' => $this->post('contractId')]) .
            hidden(['name' => 'khid', 'value' => $this->post('khid')]);
        $button = "<input style='margin-left: 5px' onclick=\"chooseRec()\" type='button' class='searchSub' value='提交'>";
        $html   = $this->search($html);
        return $this->layer(["title" => "选择收货人", "height" => 600, "width" => 1000, "html" => $html, "button" => $button]);
    }

    public function receiverSearch()
    {
        /*if (!empty($this->post('contractId'))) {
            //合同联系人
            $like  = [
                'name'    => $this->post('materialName'),
                'tel'     => $this->post('contactTel'),
                'address' => $this->post('address'),
            ];
            $equal = [
            ];
            $and   = " and orderId = '" . $this->post('khid') . "' ";
            $where = search(["like" => $like, "=" => $equal]) . $and;
            $page  = $this->page([
                "table"   => "sales_contract_address",
                "where"   => $where,
                'pageNum' => 50,
                "order"   => "`time` ASC",
            ]);
        } else {

        }*/
        //客户联系人
        $like  = [
            'name'    => $this->post('materialName'),
            'tel'     => $this->post('contactTel'),
            'address' => $this->post('address'),
        ];
        $equal = [
        ];
        $and   = " and khid = '" . $this->post('khid') . "' ";
        $where = search(["like" => $like, "=" => $equal]) . $and;
        $page  = $this->page([
            "table"   => "kehu_staff",
            "where"   => $where,
            'pageNum' => 50,
            "order"   => "`time` ASC",
        ]);

        //获取表头
        $tr[] = ['', '收货人', '收货电话', '收货地址'];
        //获取记录
        foreach ($page['array'] as $array) {
            $tr[] = [
                "<input name='peopleId' value='$array[id]' type='radio'>",
                $array['name'],
                $array['tel'],
                $array['address'],
            ];
        }
        $json['html'] = $page['hint'] .
            "<form name='recForm'>" .
            hidden(['name' => 'contractId', 'value' => $this->post('contractId')]) .
            hidden(['name' => 'khid', 'value' => $this->post('khid')]) .
            $this->tableMany(["tr" => $tr, "showSort" => true, "page" => $page['para']]) .
            "</form>" .
            $page['button'];
        return json_encode($json, 320);
    }

    /**
     * 选择合同明细
     *
     * @return bool|string
     */
    public function addContract()
    {
        if (empty($this->post('khid'))) {
            return json_encode(['warn' => '请先选择客户'], 320);
        } else {
            $type     = 'contract';
            $layerId  = $this->get('cla') . ucwords($this->get('fun'));
            $formName = 'contractForm';
            $html     =
                text(["name" => "orderNo", "title" => "合同编号"]) .
                materialClass::typeSelect() .
                text(["name" => "code", "title" => "产品编码"]) .
                text(["name" => "materialName", "title" => "产品名称"]) .
                text(["name" => "model", "title" => "规格型号"]) .
                hidden(["name" => "buttonType", "value" => $type]) .
                hidden(["name" => "contractId", "value" => $this->post('contractId')]) .
                hidden(["name" => "isTax", "value" => $this->post('isTax')]) .
                hidden(["name" => "id", "value" => $this->post('id')]) .
                hidden(["name" => "khid", "value" => $this->post('khid')]) .
                hidden(['name' => 'contract_detail_id', 'value' => $this->post('contract_detail_id') ? implode(',', $this->post('contract_detail_id')) : '']);
            $html     = $this->search($html);
            $button   = "<input onclick=\"addRow('$type');removeSelectedContent('" . $formName . "')\" type='button' class='searchSub m-l-5' value='继续添加'>";
            $button   .= "<input onclick=\"addRow('$type');$('#" . $layerId . "').remove()\" type='button' class='searchSub m-l-5' value='提交'>";
            return $this->layer(["title" => "添加", "height" => 600, "width" => 1000, "html" => $html, "button" => $button]);
        }
    }

    public function addContractSearch()
    {
        $id                 = $this->post('id');
        $contractId         = $this->post('contractId');
        $contract_detail_id = $this->post('contract_detail_id') ? explode(',', $this->post('contract_detail_id')) : [];
        $where              = " 1=1 and detail.id not in ('" . implode("','", $contract_detail_id) . "')";
        $like               = [
            'ord.orderNo' => $this->post('orderNo'),
            'a.name'      => $this->post('materialName'),
            'code'        => $this->post('code'),
            'model'       => $this->post('model'),
            'a.typePath'  => $this->post('attrName'),
        ];
        $equal              = [
            'ord.coid'       => self::$coid,
            'ord.clientId'   => $this->post('khid'),
            'detail.orderId' => $contractId,
        ];
        $where              .= search(["like" => $like, "=" => $equal]);
        $page               = $this->page([
            "table"   => "sales_contract_detail as detail join sales_contract as ord on detail.orderId = ord.id join material as a on a.id = detail.materialId",
            "field"   => "a.*,detail.id as detailId,ord.orderNo,detail.num,detail.unit as detailUnit,detail.aliasNo,detail.aliasName",
            "where"   => $where,
            'pageNum' => 50,
            "order"   => "ord.orderNo,detail.list ASC",
        ]);
        $json['sql']        = $page['fullSql'];
        $materialObj        = new materialClass();
        //获取表头
        $checkAll = $this->checkAll("contractForm", "mxId");
        $tr[]     = [$checkAll, '合同编号', '分类', '产品编码', '产品名称', '规格型号', '单位', '未进入销售单数量', '客户料号', '客户品名'];
        //获取记录
        foreach ($page['array'] as $array) {
            $dominate = [
                "box" => ["name" => "mxId", "value" => $array['detailId']],
            ];
            $checkBox = $this->dominate($dominate);
            //已进入销售单的合同明细数量
            $orderNum = $this->contractInSendNum($id, $array['detailId'], $array['detailUnit']);
            $num      = ($array['num'] - $orderNum) > 0 ? self::formattingFigure($array['num'] - $orderNum, 'numPrecision') : 0;
            $tr[]     = [
                $checkBox,
                $array['orderNo'],
                $materialObj::getTypePath($array['typeId']),
                $array['code'],
                $array['name'],
                $array['model'],
                $array['detailUnit'],
                self::lostZero($num, 'numPrecision'),
                $array['aliasNo'],
                $array['aliasName'],
            ];
        }
        $json['html'] = $page['hint'] .
            "<form name='contractForm'>" .
            hidden(["name" => "contractId", "value" => $this->post('contractId')]) .
            hidden(["name" => "isTax", "value" => $this->post('isTax')]) . $this->js() .
            hidden(["name" => "id", "value" => $id]) .
            hidden(["name" => "khid", "value" => $this->post('khid')]) .
            $this->tableMany(["tr" => $tr, "showSort" => true, "page" => $page['para']]) .
            "</form>" .
            $page['button'];
        return json_encode($json, 320);
    }

    /**
     * 编辑
     *
     * @return bool|string
     */
    public function addContractEdit()
    {
        $mxIdArr = $this->post('mxId');
        $isTax   = $this->post('isTax');     //是否含税
        $id      = $this->post('id');        //销售单ID
        if (!$this->power(self::page, 'edit')) {
            $json['warn'] = '你还没有编辑权限';
        } elseif (empty($mxIdArr) || !is_array($mxIdArr)) {
            $json['warn'] = '请选择合同明细';
        } else {
            $tr = [];
            foreach ($mxIdArr as $mxId) {
                $contractMx                   = query('sales_contract_detail', "id = '$mxId'");
                $material                     = query('material', "id = '$contractMx[materialId]'");
                $contractMx['khMaterialName'] = $contractMx['aliasName'];
                $contractMx['khMaterialCode'] = $contractMx['aliasNo'];
                //已进入销售单的合同明细数量
                $orderNum          = $this->contractInSendNum($id, $contractMx['id'], $contractMx['unit']);
                $unit              = $contractMx['unit'];
                $orderNum          = $orderNum ?: 0;
                $contractMx['num'] = $contractMx['num'] ?: 0;
                $price             = $contractMx['price'] ? self::formattingFigure($contractMx['price'], 'pricePrecision') : self::formattingFigure($material['salePrice'], 'pricePrecision');
                $num               = ($contractMx['num'] - $orderNum) > 0 ? self::formattingFigure($contractMx['num'] - $orderNum, 'numPrecision') : 0;
                $rate              = $contractMx['rate'] ?: $material['saleRate'];
                $sourceId          = $contractMx['id'] ?? '';
                $result            = self::isTax($num, $price, $rate, $isTax);
                $suiji             = self::getId();
                $tr[]              = [
                    componentClass::tablePperation('', "delTableRow(this);calculateTotal()") .
                    hidden(['name' => 'mxId[]', 'value' => $suiji]) .
                    hidden(['name' => 'materialId[]', 'value' => $material['id']]) .
                    hidden(['name' => 'contract_detail_id[]', 'value' => $sourceId]),
                    $material['code'],
                    $material['name'],
                    $material['model'],
                    select(['name' => 'unit[]', 'data' => ['unit' => $unit], 'change' => 'unitChange', 'value' => $unit, 'option' => machiningOrderClass::unitOption($material['id'])]),
                    text(['name' => 'num[]', 'type' => 'text', 'blur' => 'countMoney', 'other' => self::digitalFiltering('numPrecision'), 'value' => $num]),
                    text(['name' => 'weight[]', 'type' => 'text', 'blur' => 'countMoney', 'other' => self::digitalFiltering('numPrecision'), 'value' => 0]),
                    text(['name' => 'price[]', 'type' => 'text', 'blur' => 'countMoney', 'other' => self::digitalFiltering('pricePrecision'), 'value' => $price]),
//                    "<span class='rowMoney'>$money</span>",
//                    select(['name' => 'rate[]', 'change' => 'countMoney', 'title' => '税率', 'option' => explode('，', para('taxRate')), 'value' => $rate * 100]),
//                    "<span class='taxMoney'>$taxMoney</span>",
//                    text(['name' => 'moneyWithTax[]', 'type' => 'text', 'blur' => 'calculatePrice', 'other' => self::digitalFiltering('amount'), 'value' => $moneyWithTax]),
//                    text(['name' => 'khMaterialCode[]', 'value' => $contractMx['khMaterialCode']]),
//                    text(['name' => 'khMaterialName[]', 'value' => $contractMx['khMaterialName']]),
                    text(['name' => 'mxText[]', 'class' => 'text textPrice']),
                ];
            }
            $json['html'] = $this->tableMany(['tr' => $tr, 'thead' => false]);
            $json['warn'] = 2;
        }
        return json_encode($json, 320);
    }

    /**
     * @return bool|string
     */
    public function addMx($hidden = '')
    {
        $html =
            materialClass::typeSelect() .
            text(["name" => "code", "title" => "产品编码"]) .
            text(["name" => "materialName", "title" => "产品名称"]) .
            text(["name" => "model", "title" => "规格型号"]) .
            $hidden .
            hidden(["name" => "contractId", "value" => $this->post('contractId')]) .
            hidden(["name" => "isTax", "value" => $this->post('isTax')]) .
            hidden(["name" => "id", "value" => $this->post('id')]) .
            hidden(["name" => "khid", "value" => $this->post('khid')]) .
            hidden(['name' => 'materialId', 'value' => $this->post('materialId') ? implode(',', $this->post('materialId')) : '']);
        if ($hidden == hidden(["name" => "buttonType", "value" => 'contract'])) {
            $type = 'contract';
        } else {
            $type = 'material';
        }
        $layerId  = $this->get('cla') . ucwords($this->get('fun'));
        $formName = 'mxForm';
        $button   = "<input onclick=\"addRow('$type');removeSelectedContent('" . $formName . "')\" type='button' class='searchSub m-l-5' value='继续添加'>";
        $button   .= "<input onclick=\"addRow('$type');$('#" . $layerId . "').remove()\" type='button' class='searchSub m-l-5' value='提交'>";
        $html     = $this->search($html);
        return $this->layer(["title" => "添加", "height" => 600, "width" => 1000, "html" => $html, "button" => $button]);
    }

    /**
     * 控制允销限销
     *
     * @return bool
     */
    public static function ctrlSale(): bool
    {
        $setting = optionSettingClass::getSetting('销售');
        if (isset($setting['ctrlSale']) && $setting['ctrlSale']) {
            return true;
        }
        return false;
    }

    /**
     *添加产品
     */
    public function addMxSearch()
    {
        $contractId    = $this->post('contractId');
        $materialId    = $this->post('materialId') ? explode(',', $this->post('materialId')) : [];
        $where         = " 1=1 and a.id not in ('" . implode("','", $materialId) . "')";
        $like          = [
            'a.name'          => $this->post('materialName'),
            'code'            => $this->post('code'),
            'model'           => $this->post('model'),
            'a.typePath'      => $this->post('materialTypeId'),
            'a.supplyControl' => self::ctrlSale() ? '允许销售' : '',
        ];
        $equal         = [
            'a.state' => '启用',
        ];
        $contractMatId = [];
        if (!empty($this->post('buttonType'))) {
            $contractMat   = find(['table' => 'sales_contract_detail', 'field' => 'materialId', 'where' => " orderId = '$contractId' and materialId!='' order by list "]);
            $contractMatId = array_column($contractMat['array'], 'materialId');
            $where         .= " and a.id in ('" . implode("','", $contractMatId) . "')";
        } else {
            $where .= " and a.coid = '" . self::$coid . "'";
        }
        $where       .= search(["like" => $like, "=" => $equal]);
        $page        = $this->page([
            "table"   => "material as a",
            "field"   => "a.*",
            "where"   => $where,
            'pageNum' => 12,
            "order"   => !$this->post('buttonType') ? "a.code ASC" : "field (a.id,'" . implode("','", $contractMatId) . "')",
        ]);
        //获取表头
        $checkAll = $this->checkAll("mxForm", "mxId");
        $tr[]     = [$checkAll, '分类', '产品编码', '产品名称', '规格型号'];
        //获取记录
        foreach ($page['array'] as $array) {
            $dominate = [
                "box" => ["name" => "mxId", "value" => $array['id']],
            ];
            $checkBox = $this->dominate($dominate);
            if (!empty($this->post('buttonType')) && $array['coid'] != self::$coid) {
                $checkBox = "<span class='no-choose'>--</span>";
            }
            $tr[] = [
                $checkBox,
                $array['typeName'],
                $array['code'],
                $array['name'],
                $array['model'],
            ];
        }
        $json['html'] = $page['hint'] .
            "<form name='mxForm'>" .
            hidden(["name" => "contractId", "value" => $this->post('contractId')]) .
            hidden(["name" => "isTax", "value" => $this->post('isTax')]) . $this->js() .
            hidden(["name" => "id", "value" => $this->post('id')]) .
            hidden(["name" => "khid", "value" => $this->post('khid')]) .
            $this->tableMany(["tr" => $tr, "showSort" => true, "page" => $page['para']]) .
            "</form>" .
            $page['button'];
        return json_encode($json, 320);
    }

    /**
     * 编辑
     *
     * @return bool|string
     */
    public function addMxEdit()
    {
        $mxIdArr    = $this->post('mxId');
        $isTax      = $this->post('isTax');     //是否含税
        $id         = $this->post('id');        //销售单ID
        $khid       = $this->post('khid');      //客户ID
        $contractId = $this->post('contractId');//合同ID
        if (!$this->power(self::page, 'edit')) {
            $json['warn'] = '你还没有编辑权限';
        } elseif (empty($mxIdArr) || !is_array($mxIdArr)) {
            $json['warn'] = '请选择产品';
        } else {
            $tr = [];
            foreach ($mxIdArr as $mxId) {
                $orderNum   = 0;
                $contractMx = [
                    'num'            => 0,
                    'price'          => 0,
                    'rate'           => 0,
                    'khMaterialCode' => '',
                    'khMaterialName' => '',
                ];
                $material   = query('material', "id = '$mxId'");
                if ($contractId) {
                    //如果是从合同明细中选择的，则带出合同明细的数据
                    $contractMx                   = query('sales_contract_detail', "materialId = '$mxId' and orderId = '$contractId'");
                    $contractMx['khMaterialName'] = $contractMx['aliasName'];
                    $contractMx['khMaterialCode'] = $contractMx['aliasNo'];
                    //已进入销售单的合同明细数量
                    $orderNum = $this->contractInSendNum($id, $contractMx['id'], $contractMx['unit']);
                    $unit     = $contractMx['unit'];
                } else {
                    $store_client_price           = query('store_client_price', "khid = '$khid' and materialId = '$material[id]' order by time desc");
                    $contractMx['khMaterialName'] = $store_client_price['materialAlias'];
                    $contractMx['khMaterialCode'] = $store_client_price['materialAliasNo'];
                    $contractMx['price']          = $store_client_price['dealPrice'];
                    $unit                         = $material['unit'];
                }

                $orderNum          = $orderNum ?: 0;
                $contractMx['num'] = $contractMx['num'] ?: 0;
                $price             = $contractMx['price'] ?
                    self::formattingFigure($contractMx['price'], 'pricePrecision') :
                    self::formattingFigure($material['salePrice'], 'pricePrecision');
                $num               = ($contractMx['num'] - $orderNum) > 0 ?
                    self::formattingFigure($contractMx['num'] - $orderNum, 'numPrecision') :
                    0;
                $rate              = $contractMx['rate'] ?: $material['saleRate'];
                $sourceId          = $contractMx['id'] ?? '';
                $suiji             = self::getId();
                $tr[]              = [
                    componentClass::tablePperation('', "delTableRow(this);calculateTotal()") .
                    hidden(['name' => 'mxId[]', 'value' => $suiji]) .
                    hidden(['name' => 'materialId[]', 'value' => $mxId]) .
                    hidden(['name' => 'contract_detail_id[]', 'value' => $sourceId]),
                    $material['code'],
                    $material['name'],
                    $material['model'],
                    select(['name' => 'unit[]', 'data' => ['unit' => $unit], 'change' => 'unitChange', 'value' => $unit, 'option' => machiningOrderClass::unitOption($material['id'])]),
                    text(['name' => 'num[]', 'type' => 'text', 'blur' => 'countMoney', 'other' => self::digitalFiltering('numPrecision'), 'value' => $num]),
                    text(['name' => 'weight[]', 'type' => 'text', 'blur' => 'countMoney', 'other' => self::digitalFiltering('numPrecision'), 'value' => 0]),
                    text(['name' => 'price[]', 'type' => 'text', 'blur' => 'countMoney', 'other' => self::digitalFiltering('pricePrecision'), 'value' => $price]),
                    text(['name' => 'mxText[]', 'class' => 'text textPrice']),
                ];
            }
            $json['html'] = $this->tableMany(['tr' => $tr, 'thead' => false]);
            $json['warn'] = 2;
        }
        return json_encode($json, 320);
    }

    public function js()
    {
        return <<<efo
<script>
$(function (){
    $(".no-choose").parent().parent().css('color','#d7d7d7');
    $(".no-choose").parent().parent().attr('title','不是当前账套的产品，不可选择');
})
</script>
efo;
    }

    /**
     * 根据是否含税计算价税合计和税额
     */
    public static function isTax($num, $price, $rate, $isTax = 0): array
    {
        $money = $moneyWithTax = $taxMoney = 0;
        if (!isZero($num, $price)) {
            if ($isTax) {
                //含税
                $moneyWithTax = self::formattingFigure($num * $price, 'amount');
                $taxMoney     = self::formattingFigure($moneyWithTax / (1 + $rate) * $rate, 'amount');
            } else {
                //不含税
                $taxMoney     = self::formattingFigure($num * $price * $rate, 'amount');
                $moneyWithTax = self::formattingFigure($num * $price * (1 + $rate), 'amount');
            }
            $money = $moneyWithTax - $taxMoney;
        }
        return ['money' => $money, 'taxMoney' => $taxMoney, 'moneyWithTax' => $moneyWithTax];
    }


    /**
     * 销售合同已进入销售单中的数量
     */
    private function contractInSendNum($saleOrderId, $contractMxId, $toUnit): float|int
    {
        $orderNum = 0;
        $all      = find(['table' => 'sale_order_detail', 'where' => " orderId !='$saleOrderId' and contract_detail_id = '$contractMxId' and coid = '" . self::$coid . "'"]);
        foreach ($all['array'] as $array) {
            $orderNum += machiningOrderClass::material_num_change($array['materialId'], $array['unit'], $toUnit, $array['num']);
        }
        return $orderNum;
    }


    /**
     * 启用/停用
     */
    public function stateSwitch(): bool|string
    {
        $isClose = $this->post('type');
        //生成表单
        $html = $this->layerEdit([
            "table"     => [
                [
                    "提示：" => "是否确认" . ($isClose == 1 ? '关闭业务' : '开启业务') . "此订单？",
                ],
            ], 'hidden' => hidden(['name' => 'type', 'value' => $isClose]),
        ]);
        //返回
        return $this->layer(["title" => "订单状态", "height" => 165, "html" => $html, 'formTwo' => 'listForm']);
    }

    /**
     * 启用/停用
     */
    public function stateSwitchEdit(): bool|string
    {
        $idArr   = $this->post('id') ? [$this->post('id')] : $this->post('listId');
        $isClose = $this->post('type');
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有" . self::title . "的编辑权限";
        } elseif (empty($idArr) || !is_array($idArr)) {
            $json['warn'] = "请选择数据";
        } else {
            $field        = [
                'isClose' => $isClose,
            ];
            $json['warn'] = update(['table' => self::table, 'field' => $field, 'where' => " id in ('" . implode("','", $idArr) . "')"]);
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                $type = $isClose == 1 ? '关闭' : '开启';
                //关闭产品需求计划
                if ($isClose == 1) {
                    update(['table' => 'product_demands', 'field' => ['isClear' => 1], 'where' => " sourceId in ('" . implode("','", $idArr) . "')"]);
                }
                foreach ($idArr as $id) {
                    self::insertOperateLog($id, self::title, $type);
                }
                //添加日志
                $text = $this->control['name'] . $type . "了" . self::title . "， id：【" . implode(",", $idArr) . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $type . '成功';
                $json['warn']     = 2;
            }
        }
        //返回
        return json_encode($json, 320);
    }

    /*详情页*/
    public function detail(): string
    {
        $info = query(self::table, " id = '{$this->get('id')}'");
        if (empty($info['id'])) {
            $html = '未找到此' . self::title;
        } else {
            //菜单
            $data   = ["id" => $info['id']];
            $button = [];
            if ($info['state'] == '草稿') {
                if ($this->power(self::page, "edit")) {
                    //按钮
                    $button[] = [
                        "name"  => "提交",
                        "type"  => "弹出层",
                        "cla"   => $this->get('cla'),
                        "fun"   => "operate",
                        "post"  => ["act" => 'commit', "id" => $info['id']],
                        'style' => 'li-btn-blue-bg',
                    ];
                    //按钮
                    $button[] = [
                        "name"  => "编辑",
                        "type"  => "顶部页卡",
                        "title" => "编辑用户",
                        "url"   => $this->root . "control/adIndex.html?cla={$this->get('cla')}&fun=edit&id=" . $info['id'],
                    ];
                }
                if ($this->power(self::page, "del")) {
                    //按钮
                    $button[] = [
                        "name" => "删除",
                        "type" => "弹出层",
                        "cla"  => $this->get('cla'),
                        "fun"  => "operate",
                        "post" => ["act" => 'del', "id" => $info['id']],
                    ];
                }
            }
            //按钮
            $button[] = [
                "name" => "打印",
                "type" => "点击事件",
                "fun"  => "window.open('" . root . "control/adIndex.html?cla=" . self::page . "&fun=printPage&id={$info['id']}')",
            ];
            if ($this->power(self::page, "confirm") && $info['state'] == '待确认') {
                $button[] = [
                    "name"  => "复核",
                    "type"  => "弹出层",
                    "cla"   => $this->get('cla'),
                    "fun"   => "operate",
                    "post"  => ["act" => 'confirm', "id" => $info['id']],
                    'style' => 'li-btn-blue-bg',
                ];
            }
            if ($this->power(self::page, "cancel") && $info['state'] != '草稿' && !$info['isClose']) {
                $button[] = [
                    "name"  => "发货",
                    "type"  => "顶部页卡",
                    "title" => "发货单详情",
                    "url"   => $this->root . "control/adIndex.html?cla=saleSendOrder&fun=edit&orderId=" . $info['id'],
                ];
//                $button[] = [
//                    "name" => "撤回",
//                    "type" => "弹出层",
//                    "cla"  => $this->get('cla'),
//                    "fun"  => "operate",
//                    "post" => ["act" => 'cancel', "id" => $info['id']],
//                ];
            }
            if ($this->power(self::page, "edit") && $info['state'] == '已确认') {
                //按钮
                $isClose  = $info['isClose'] == 1 ? 0 : 1;
                $name     = $info['isClose'] == 1 ? '业务开启' : '业务关闭';
                $button[] = [
                    "name" => $name,
                    "type" => "点击事件",
                    "fun"  => "layer('" . self::page . "','stateSwitch',{id:'" . $info['id'] . "',type:'{$isClose}'})",
                ];
            }
            $button[] = [
                "name"  => "单据追踪",
                "type"  => "顶部页卡",
                "title" => "单据追踪",
                "url"   => $this->root . "control/adIndex.html?cla=orderTrack&fun=home&orderType=销售订单&id=" . $info['id'],
            ];
            //操作记录
            $button[] = self::operateLogBut($info['id'], 1);
            $kehu           = query('kehu', "khid = '$info[khid]'");
            $sales_contract = query('sales_contract', "id = '$info[contractId]'");
            $tr[]           = ['产品编码', '产品名称', '规格型号', '单位', '数量',  '气瓶数量', '单价(' . static::$unit . ')', '备注'];
            $result         = find(['table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list"]);
            foreach ($result['array'] as $array) {
                $material = query('material', " id = '$array[materialId]'");
                $tr[]     = [
                    $material['code'],
                    $material['name'],
                    $material['model'],
                    $array['unit'],
                    self::lostZero($array['num'], 'numPrecision'),
                    self::lostZero($array['weight'], 'numPrecision'),
                    self::lostZero($array['price'], 'pricePrecision'),
                    $array['text'],
                ];
            }
//            $total    = find([
//                'table'  => self::tableMx,
//                'field'  => "ifnull(sum(num),0) as num,ifnull(sum(money),0) as totalMoney,ifnull(sum(taxMoney),0) as taxMoney,ifnull(sum(money-taxMoney),0) as money",
//                'single' => "orderId = '$info[id]'",
//            ]);
            //生成表单
            $data['button'] = $this->tableShowButton($button);
            $data['html']   = $this->tableShow([
                "详细信息" => [
                    [
                        "单据日期" => self::null($info['recordDate']),
                        "客户"   => $kehu['companyName'],
                        "信用额度" => $kehu['credits'] . '/0',
                        "合同名称" => $sales_contract['name'],
                    ],
                    [
                        "收货人"  => $info['contactName'],
                        "收货电话" => $info['contactTel'],
                        "收货地址" => $info['address'],
                        "交货方式" => self::deliveryMethod[$info['delivery_method']],
                    ],
                    [
                        "结算方式" => $info['settlementType'] . ($info['settlementType'] == '月结' ? '-' . $info['settlementDay'] . '天' : ''),
                        "交货日期" => self::null($info['deliveryDate']),
                        "单据编号" => $info['orderNo'],
                        "销售人"  => self::findStaff($info['manager']),
                    ],
                    [
                        "制单人"  => self::findStaff($info['stid']),
                        "状态"   => $info['state']. self::operateRecord($info['id']),
                        "备注" => pre($info['text']),
                    ],
                    [
                        '单据标签' => orderTagClass::getTagName($info['id']),
                    ],
                ],
            ]);
            $data['html']   .= $this->detailList([
                'title' => '销售明细',
                'html'  => $this->listTable(['tr' => $tr, 'showEmpty' => true, 'total' => [], 'showSort' => true]),
            ]);
            $data['html']   .= $this->detailBlock([
                '附件' => fileUploadClass::showFile($info['id'], '销售单')
            ]);
            //生成页面
            $html = $this->tab($data);
        }
        //返回
        return $html;
    }

    /**
     * 操作记录
     */
    public static function operateRecord($id): string
    {
        $result = find(['table' => 'auditing_follow', 'where' => "typeId = '$id' order by time desc"]);
        $li     = '';
        if (is_array($result['array'])) {
            foreach ($result['array'] as $array) {
                $li .= "<li>{$array['text']}&emsp;{$array['time']}</li>";
            }
        }
        if (empty($li)) {
            $li = "<li>暂无记录</li>";
        }
        return "&emsp;<span class='del-row-button' id='record'>操作记录<div class='stateBlock operate-content'><ul>$li</ul></div></span>";
    }

    /**
     * 确认
     */
    public function confirmEdit()
    {
        $id    = $this->post('id');
        $info  = query(self::table, " id = '$id'");
        $field = [
            'state'       => '已确认',
            'checkId'     => self::$stid,
            'confirmTime' => $this->time,
        ];
        $warn  = '';
        //判断客户信用额度
        $setting = optionSettingClass::getSetting('销售');
        if (isset($setting['creditCtrl']['option']) && $setting['creditCtrl']['option'] && $setting['creditCtrl']['way'] == '复核') {
            $kehu    = query('kehu', "khid = '$info[khid]'");
            $balance = saleOrderClass::clientBalance($info['khid']);
            if ($kehu['credits'] < round($balance, 2)) {
                $warn = '客户信用额度不足';
            }
        }
        if (!$this->power(self::page, 'confirm')) {
            $json['warn'] = '你还没有确认权限';
        } elseif (empty($info['id'])) {
            $json['warn'] = '未找到此销售单';
        } elseif ($info['state'] != '待确认') {
            $json['warn'] = '此销售单不是待确认状态，不能确认';
        } elseif ($warn) {
            $json['warn'] = $warn;
        } else {
            $this->startTrans();
            $json['warn'] = '新增成功';
            //生成产品需求单
            $bool = $this->product_demands($info['id']);
            if ($bool !== true) {
                $json['warn'] = $bool;
            }
            //生成外购需求单
            $bool = $this->purchase_demands($info['id']);
            if ($bool !== true) {
                $json['warn'] = $bool;
            }
            //生成委外需求单
            $bool = $this->outsource_demands($info['id']);
            if ($bool !== true) {
                $json['warn'] = $bool;
            }
            //生产销售发货单
            $bool = $this->sale_send_data($info['id']);
            if ($bool !== true) {
                $json['warn'] = $bool;
            }
            //对接旭永接口
            $tokenData = $this->getToken();
            if(!$tokenData['code']){
                $json['warn'] = $tokenData['msg'];
            }else{
                $kehu           = query('kehu', "khid = '$info[khid]'");
                $goodsData = find(['table'=>self::tableMx,'where'=>"coid = '" . self::$coid . "' and orderId = '$info[id]'"]);
                $goods = [];
                foreach ($goodsData['array'] as $item){
                    $material = query('material', " id = '$item[materialId]'");
                    $goods[] = [
                        'name' => $material['name'],//商品名称
                        'medium' => $material['model'],//商品介质
                        'price' => $item['price'],//参考单价
                        'num' => $item['num'],//重量
                        'count' => self::lostZero($item['weight'], 'numPrecision'),//数量
                    ];
                }
                $post_data = [
//                    'id' => $info['id'],//订单id
                    'no' => $info['orderNo'].'3',//顶单编号
                    'custName' => $kehu['companyName'],//客户名称
                    'custContcat' => $info['contactName'],//客户联系人
                    'custPhone' => $info['contactTel'],//客户电话
                    'addr' => $info['address'],//客户地址
                    'sender' => self::findStaff($info['delivery_name']),//配送员
                    'goods' => $goods,//商品列表
                ];
                $customerEdit = $this->send_post("txhg/orderEdit",$post_data,$tokenData['data']);
                if($customerEdit['code'] !== '1'){
                    $json['warn'] = "上传接口返回失败；失败原因：".$customerEdit['msg'];
                }else{
                    $field['postId'] = $customerEdit['data']['ID'];
                    if (in_array($json['warn'], ["新增成功", "更新成功"])){
                        $json['warn'] = update([
                            "table" => self::table,
                            "field" => $field,
                            "where" => "id = '$info[id]'",
                        ]);
                    }
                }
            }
            //生成物流发货单
            if ($info['delivery_method'] == 2) {
                $bool = self::delivery_order($info['id']);
                if ($bool !== true) {
                    $json['warn'] = $bool;
                }
            }
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                $this->commitTrans();
                // 单据是否需要复核
                if (!in_array(self::page, self::$publicSettings['documentReview'])) {
                    self::insertOperateLog( $info['id'], self::title, "提交、复核");
                } else {
                    self::insertOperateLog($info['id'], self::title, "复核");
                }
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . "id：【" .  $info['id'] . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn']     = 2;
                $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
            } else {
                $this->rollback();
            }
        }
        resp:
        return json_encode($json, 320);
    }

    /**
     * 生成物流发货单
     */
    public static function delivery_order($id): bool|string
    {
        $info             = query("sale_order", " id = '$id' ");
        $field            = [
            'id'          => suiji(),
            'coid'        => self::$coid,
            'sourceTable' => 'sale_order',
            'sourceId'    => $id,
            'khid'        => $info['khid'],
            'manager'     => $info['manager'],
            'contractId'  => $info['contractId'],
            'recordDate'  => $info['recordDate'],
            'limitTime'   => $info['deliveryDate'],
            'text'        => $info['text'],
            'contactName' => $info['contactName'],
            'contactTel'  => $info['contactTel'],
            'address'     => $info['address'],
            'money'       => $info['money'],
            'isTax'       => $info['isTax'],
            'stid'        => $info['stid'],
            'updateTime'  => date("Y-m-d H:i:s"),
            'time'        => date("Y-m-d H:i:s"),
        ];
        $field['orderNo'] = codeTemplateClass::generateCode('deliveryManage', [
            'prefix' => 'XSFH' . date('Ymd', strtotime($field['recordDate'])),
            'table'  => 'delivery_order',
            'field'  => 'orderNo',
            'where'  => " and coid = '" . self::$coid . "'",
        ], $field);
        $warn             = static::insert([
            'table' => 'delivery_order',
            'field' => $field,
        ]);
        if ($warn != '新增成功') {
            return '生成物流发货单失败';
        }

        $all = find([
            'table' => "sale_order_detail as a",
            'field' => "a.*",
            'where' => "a.orderId = '$id' and a.coid = '" . self::$coid . "' order by a.list asc",
        ]);
        foreach ($all['array'] as $array) {
            $warn = static::insert([
                'table' => 'delivery_order_detail',
                'field' => [
                    'id'              => suiji(),
                    'coid'            => self::$coid,
                    'orderId'         => $field['id'],
                    'sourceTable'     => 'sale_order_detail',
                    'sourceId'        => $array['id'],
                    'saleOrderMxId'   => $array['id'],
                    'khMaterialCode'  => $array['khMaterialCode'],
                    'khMaterialName'  => $array['khMaterialName'],
                    'materialId'      => $array['materialId'],
                    'warehouseId'     => '',
                    'num'             => $array['num'],
                    'unit'            => $array['unit'],
                    'price'           => $array['price'],
                    'taxMoney'        => $array['taxMoney'],
                    'moneyWithOutTax' => $array['moneyWithOutTax'],
                    'rate'            => $array['rate'],
                    'money'           => $array['money'],
                ],
            ]);
            if ($warn != '新增成功') {
                return '生成物流发货明细失败';
            }
        }
        return true;
    }


    /**
     * 委外需求
     *
     * @param $id
     * @return bool|string
     */
    public static function outsource_demands($id): bool|string
    {
        $all = find([
            'table' => "sale_order_detail as a join sale_order as b on a.orderId = b.id join material as c on c.id = a.materialId",
            'field' => "a.*,b.recordDate,b.orderNo",
            'where' => "b.id = '$id' and c.source = '委外' order by a.list desc",
        ]);
        foreach ($all['array'] as $array) {
            $warn = static::insert([
                'table' => 'outsource_demands',
                'field' => [
                    'id'          => suiji(),
                    'coid'        => self::$coid,
                    'sourceType'  => '销售订单',
                    'sourceTable' => 'sale_order',
                    'sourceId'    => $array['orderId'],
                    'sourceMxId'  => $array['id'],
                    'sourceDate'  => $array['recordDate'],
                    'sourceNo'    => $array['orderNo'],
                    'materialId'  => $array['materialId'],
                    'num'         => $array['num'],
                    'unit'        => $array['unit'],
                ],
            ]);
            if ($warn != '新增成功') {
                return '生成委外需求计划失败';
            }
        }
        return true;
    }

    /**
     * 生成外购需求单
     */
    public static function purchase_demands($id): bool|string
    {
        $all = find([
            'table' => "sale_order_detail as a join sale_order as b on a.orderId = b.id join material as c on c.id = a.materialId",
            'field' => "a.*",
            'where' => "b.id = '$id' and c.source = '采购' order by a.list desc",
        ]);
        foreach ($all['array'] as $array) {
            $lastSupplier = find([
                'table'  => 'purchase_order as a join purchase_order_detail as b on a.id = b.orderId',
                "single" => "b.materialId = '$array[materialId]' and a.state = '已确认' order by list desc",
                'field'  => "supplierId",
            ]);
            $warn         = static::insert([
                'table' => 'purchase_demands',
                'field' => [
                    'id'          => suiji(),
                    'coid'        => self::$coid,
                    'sourceType'  => '销售订单',
                    'sourceTable' => 'sale_order',
                    'sourceId'    => $array['orderId'],
                    'sourceMxId'  => $array['id'],
                    'materialId'  => $array['materialId'],
                    'num'         => $array['num'],
                    'unit'        => $array['unit'],
                    'supplierId'  => $lastSupplier['supplierId'] ?? '',
                ],
            ]);
            if ($warn != '新增成功') {
                return '生成外购需求计划失败';
            }
        }
        return true;
    }

    /**
     * 生成产品需求单
     */
    public static function product_demands($id): bool|string
    {
        $all = find([
            'table' => "sale_order_detail as a join sale_order as b on a.orderId = b.id join material as c on c.id = a.materialId",
            'field' => "a.*",
            'where' => "b.id = '$id' and c.source = '自制' order by a.list desc",
        ]);
        foreach ($all['array'] as $array) {
            $warn = static::insert([
                'table' => 'product_demands',
                'field' => [
                    'id'          => suiji(),
                    'coid'        => self::$coid,
                    'sourceTable' => 'sale_order',
                    'sourceId'    => $array['orderId'],
                    'sourceMxId'  => $array['id'],
                    'materialId'  => $array['materialId'],
                    'num'         => $array['num'],
                    'unit'        => $array['unit'],
                ],
            ]);
            if ($warn != '新增成功') {
                return '生成产品需求计划失败';
            }
        }
        return true;
    }

    /**
     * 生成产品需求单
     */
    public static function sale_send_data($id): bool|string
    {
        $info = query(self::table,"id='$id'");
        $field               = [
            'text'                 => $info['text'],
            'contractId'           => $info['contractId'],
            'khid'                 => $info['khid'],
            'recordDate'           => $info['recordDate'],
            'limitTime'            => $info['recordDate'],
            'contactName'          => $info['contactName'],
            'contactTel'           => $info['contactTel'],
            'address'              => $info['address'],
            'isTax'                => $info['isTax'] ? 1 : 0,
            'settlementType'       => $info['address'],
            'settlementDay'        => $info['settlementDay'],
            'delivery_method'      => $info['delivery_method'],
            'delivery_manage'      => $info['delivery_manage'],
            'actual_delivery_date' => $info['actual_delivery_date'],
            'orderId' => $info['id'],
        ];
        $userNo       = codeTemplateClass::generateCode(self::page, [
            'prefix' => 'XSFH' . date('Ymd', strtotime($field['recordDate'])),
            'table'  => 'sale_send_order',
            'field'  => 'orderNo',
            'where'  => " and coid = '" . self::$coid . "'",
        ], $field);
        $field        = array_merge($field, [
            'id'      => self::getId(),
            'orderNo' => $userNo,
            'state'   => '草稿',
            'coid'    => self::$coid,
            'stid'    => $info['stid'],
        ]);
        $sale_send_order = static::insert(["table" => 'sale_send_order', "field" => $field]);
        $all = find([
            'table' =>self::tableMx,
            'where' => "orderId = '$info[id]' order by list desc",
        ]);
        foreach ($all['array'] as $array) {
            $result            = saleOrderClass::isTax($array['num'], $array['price'], 13);
            $warn = static::insert([
                "table" => 'sale_send_order_detail',
                "field" => [
                    'id'               => self::getId(),
                    'orderId'          => $field['id'],
                    'coid'             => self::$coid,
                    'sourceTable'      => self::tableMx,
                    'saleOrderMxId'    => $array['id'],
                    'materialId'       => $array['materialId'],
                    'unit'             => $array['unit'],
                    'num'              => $array['num'],
                    'packing_quantity' => '',
                    'box_capacity'     => '',
                    'remainder'        => '',
                    'batch'            => '',
                    'price'            => $array['price'],
                    'taxMoney'         => $result['taxMoney'],//税额
                    'moneyWithOutTax'  => $result['moneyWithTax'],//不含税金额
                    'money'            => $result['money'],//价税合计
                    'rate'             => 13,
                    'warehouseId'      => '',
                    'positionId'       => '',
                    'khMaterialCode'   => '',
                    'khMaterialName'   => '',
                    'text'   => '',
                ],
            ]);
            if ($warn != '新增成功') {
                return '生成产品需求计划失败';
            }
        }
        return true;
    }

    /**
     * 撤回
     */
    public function cancelEdit()
    {
        $id    = $this->post('id');
        $info  = query(self::table, " id = '$id'");
        $field = [
            'state'       => '草稿',
            'checkId'     => '',
            'confirmTime' => '',
        ];
        if (!$this->power(self::page, 'cancel')) {
            $json['warn'] = '你还没有撤回权限';
        } elseif (empty($info['id'])) {
            $json['warn'] = '未找到此销售单';
        } elseif ($info['state'] == '草稿') {
            $json['warn'] = '此销售单草稿状态，无需撤回';
        } elseif (static::total(['table' => 'sale_send_order_detail', "where" => "saleOrderMxId in (select id from " . self::tableMx . " where orderId = '$info[id]') and coid = '" . self::$coid . "'"]) > 0) {
            $json['warn'] = '此销售单已存在有发货的单据，不能撤回';
        } elseif (static::total(['table' => 'purchase_order_detail', "where" => "sourceId in (select id from " . self::tableMx . " where orderId = '$info[id]') and coid = '" . self::$coid . "'"]) > 0) {
            $json['warn'] = '此销售单已存在有采购的单据，不能撤回';
        } else {
            $this->startTrans();
            $json['warn'] = update([
                "table" => self::table,
                "field" => $field,
                "where" => "id = '$info[id]'",
            ]);

            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                $this->commitTrans();
                delete(['table' => 'product_demands', 'where' => "sourceId = '$info[id]'"]);
                delete(['table' => 'purchase_demands', 'where' => "sourceId = '$info[id]'"]);
                delete(['table' => 'outsource_demands', 'where' => "sourceId = '$info[id]'"]);
                self::insertOperateLog($id, self::title, "撤回");
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn']     = 2;
                $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
            } else {
                $this->rollback();
            }
        }
        resp:
        return json_encode($json, 320);
    }

    /**
     * 保存并提交
     * @return bool|string
     */
    public function saveAndCommit(): bool|string
    {
        $resultJson = $this->editEdit();
        $result     = json_decode($resultJson, true);
        if ($result['warn'] == 2) {
            unset($_SESSION['warn']);
            $resultJson = $this->commitEdit();
        }
        return $resultJson;
    }

    /**
     * Desc : 提交前数据验证
     * User : you name
     * Date : 2023-11-17 16:04
     * @param $info
     * @return string|bool
     */
    public function dataValidation($info): string|bool
    {
        $annotation = [
            'orderNo'         => '单据编号',
            'type'            => '业务类型',
            'khid'            => '客户',
            'recordDate'      => '单据日期',
            'delivery_method' => '交货方式',
            'settlementType'  => '结算方式',
            'deliveryDate'    => '交货日期',
        ];
        $rules      = [
            'orderNo'         => 'required',
            'type'            => 'required',
            'khid'            => 'required',
            'recordDate'      => 'required|date',
            'delivery_method' => 'required',
            'settlementType'  => 'required',
            'deliveryDate'    => 'required|date',
        ];
        // 校验是否符合规则
        $vt     = new \verify();
        $result = $vt->setAliases($annotation)->validate($info, $rules)->isOk();
        if ($result === false) {
            return $vt->getErrs()[0];  // 多个规则提示最前面一条
        }
        if ($info['settlementType'] == '月结' && empty($info['settlementDay'])) {
            return '月结的结算周期不能为空';
        }
        //判断客户信用额度
        $setting = optionSettingClass::getSetting('销售');
        if (isset($setting['creditCtrl']['option']) && $setting['creditCtrl']['option'] && $setting['creditCtrl']['way'] == '保存') {
            $kehu    = query('kehu', "khid = '$info[khid]'");
            $balance = self::clientBalance($info['khid']);
            if ($kehu['credits'] < $balance) {
                return '客户信用额度不足';
            }
        }

        $result = find(['table' => self::tableMx, 'field' => 'id,materialId,unit,num,price,contract_detail_id', 'where' => "orderId = '$info[id]' order by list"]);
        if (count($result['array']) == 0) {
            return "请完善订单明细";
        }
        if (static::is_null_array(array_column($result['array'], 'materialId'))) {
            return "订单明细中【产品】不能为空";
        }
        if (static::is_null_array(array_column($result['array'], 'unit'))) {
            return "订单明细中【单位】不能为空";
        }
        if (static::is_null_array(array_column($result['array'], 'price'))) {
            return "订单明细中【单价】不能为空";
        }
        if (static::is_null_array(array_column($result['array'], 'num'), false)) {
            return "订单明细中【数量】不能为空，且必须大于0";
        }

        foreach ($result['array'] as $k => $array) {
//            $mxId = $array['id'];
            if (isset($array['contract_detail_id']) && $array['contract_detail_id']) {
                //判断数量是否超出销售合同
                //销售合同明细
//                $num        = 0;
                $targetInfo = query('sales_contract_detail', "id = '" . $array['contract_detail_id'] . "'");
                $material = query('material', "id = '$targetInfo[materialId]'");
//                $orderNum = machiningOrderClass::material_num_change($targetInfo['materialId'], $array['unit'], $material['unit'], $array['num']); //当前单据数量
//                $all        = find([
//                    'table' => 'sale_order_detail',
//                    "where" => "contract_detail_id = '" . $array['contract_detail_id'] . "' and id !='$mxId' and coid = '" . self::$coid . "' and materialId = '".$targetInfo['materialId']."'",
//                ]);
//                foreach ($all['array'] as $value) {
//                    $num      += machiningOrderClass::material_num_change($value['materialId'], $value['unit'], $material['unit'], $value['num']);
//                }
                $targetInfo['num'] = machiningOrderClass::material_num_change($targetInfo['materialId'], $targetInfo['unit'], $material['unit'], $targetInfo['num']);
//                if ($num + $orderNum > $targetInfo['num']) {
//                    $over = $num + $orderNum - $targetInfo['num'];
//                    return "产品【{$material['name']}】的数量已超出销售合同明细中数量【{$over}】";
//                }
            }
        }

        return true;
    }

    /**
     * 确认
     */
    public function batchSureEdit()
    {
        $array = $this->post('listId') ?? $this->post('id');
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有操作的权限";
        } elseif (empty($array)) {
            $json['warn'] = "你一个数据都没有选择呢";
        } else {
            $text  = "";
            $x     = 0;
            $array = is_array($array) ? $array : [$array];
            foreach ($array as $id) {
                $info  = query(self::table, " id = '$id'");
                $field = [
                    'state'       => '已确认',
                    'checkId'     => self::$stid,
                    'confirmTime' => $this->time,
                ];
                if (empty($info['id'])) {
                    $json['warn'] = '未找到此销售单';
                    goto resp;
                } elseif (!in_array($info['state'], ['草稿', '待确认'])) {
                    $json['warn'] = '此销售单不是草稿、待确认状态，不能确认';
                    goto resp;
                }
                //判断客户信用额度
                $setting = optionSettingClass::getSetting('销售');
                if (isset($setting['creditCtrl']['option']) && $setting['creditCtrl']['option'] && $setting['creditCtrl']['way'] == '复核') {
                    $kehu    = query('kehu', "khid = '$info[khid]'");
                    $balance = saleOrderClass::clientBalance($info['khid']);
                    if ($kehu['credits'] < round($balance, 2)) {
                        $json['warn'] = '客户信用额度不足';
                        goto resp;
                    }
                }
                $this->startTrans();
                $json['warn'] = update([
                    "table" => self::table,
                    "field" => $field,
                    "where" => "id = '$info[id]'",
                ]);
                //生成产品需求单
                $bool = $this->product_demands($info['id']);
                if ($bool !== true) {
                    $json['warn'] = $bool;
                    goto resp;
                }
                //生成外购需求单
                $bool = $this->purchase_demands($info['id']);
                if ($bool !== true) {
                    $json['warn'] = $bool;
                    goto resp;
                }
                //生成委外需求单
                $bool = $this->outsource_demands($info['id']);
                if ($bool !== true) {
                    $json['warn'] = $bool;
                    goto resp;
                }
                //生成物流发货单
                $optionSetting = optionSettingClass::getSetting('物流');  //选项设置
                $sourceOrder   = $optionSetting['sourceOrder'] ?: [];     //物流发货依据
                if ($info['delivery_method'] == 2 && in_array('saleOrder', $sourceOrder)) {
                    $bool = self::delivery_order($info['id']);
                    if ($bool !== true) {
                        $json['warn'] = $bool;
                        goto resp;
                    }
                }
                resp:
                if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                    $this->commitTrans();
                    if ($info['state'] == '草稿') {
                        $operate = "提交，确认";
                    } else {
                        $operate = "确认";
                    }
                    auditClass::operateRecord($id, '销售单', $operate);
                    //添加日志
                    $warn = $operate . "成功";
                    $x++;
                } else {
                    $this->rollback();
                    $warn = $json['warn'];
                }

                $text .= self::title . "单据编号【" . $info['orderNo'] . "】，ID【" . $id . "】" . $warn . "。<br>";
            }
            //添加日志
            $text = $this->control['name'] . "提交，确认了" . self::title . "，结果如下：<br>" . $text;
            $this->logText(["type" => self::page, "text" => $text]);
            $_SESSION['warn'] = "提交，确认了" . $x . "个" . self::title . "，详情见系统日志。";
            $json['warn']     = 2;
            $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
        }
        return json_encode($json, 320);
    }

    /**
     * 提交
     */
    public function commitEdit()
    {
        $id    = $this->post('id');
        $info  = query(self::table, " id = '$id'");
        $field = [
            'state' => '待确认',
        ];
        //提交前数据验证
        $json['warn'] = $this->dataValidation($info);
        if ($json['warn'] !== true) {
            goto resp;
        }
        if (!$this->power(self::page, 'edit')) {
            $json['warn'] = '你还没有编辑权限';
        } elseif (empty($info['id'])) {
            $json['warn'] = '未找到此销售单';
        } elseif ($info['state'] != '草稿') {
            $json['warn'] = '此销售单不是草稿状态，不能提交';
        } else {
            $this->startTrans();
            $json['warn'] = update([
                "table" => self::table,
                "field" => $field,
                "where" => "id = '$info[id]'",
            ]);
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                // 单据是否需要复核
                if (!in_array(self::page, self::$publicSettings['documentReview'])) {
                    $resultJson = $this->confirmEdit();
                    $json       = json_decode($resultJson, true);
                    if ($json['warn'] != 2) {
                        $this->rollback();
                        goto resp;
                    }
                } else {
                    self::insertOperateLog($info['id'], self::title, "提交");
                }
                $this->commitTrans();
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn']     = 2;
                $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
            } else {
                $this->rollback();
            }
        }
        resp:
        return json_encode($json, 320);
    }

    // 操作中转
    public function operate()
    {
        $act  = $this->post('act') ?? '';
        $pwd  = $word = false; // 需要密码
        $form = $power = '';
        switch ($act) {
            case 'confirm':
                $act      = 'confirm';
                $msg      = '确认';
                $title    = '是否已确认此销售单，确认后将不可修改？';
                $function = 'confirmEdit';
                $form     = self::page . 'OperateForm, detailForm';
                $power    = '';
                $word     = true;
                break;
            case 'commit':
                $act      = 'edit';
                $msg      = '编辑';
                $title    = '是否确认提交此销售单？';
                $function = 'commitEdit';
                $form     = self::page . 'OperateForm, detailForm';
                $power    = '';
                $word     = true;
                break;
            case 'cancel':
                $act      = 'cancel';
                $msg      = '撤回';
                $title    = '是否确认撤回此销售单？';
                $function = 'cancelEdit';
                $form     = self::page . 'OperateForm, detailForm';
                $power    = '';
                $word     = true;
                break;
            case 'close':
                $act      = 'close';
                $msg      = '业务关闭';
                $title    = '是否确认批量关闭销售单？';
                $function = 'closeEdit';
                $form     = self::page . 'OperateForm, listForm, quoForm';
                $power    = '';
                $word     = true;
                break;
            case 'batchSure':
                $act      = 'edit';
                $msg      = '提交确认';
                $title    = '是否确认批量提交确认销售单？';
                $function = 'batchSureEdit';
                $form     = self::page . 'OperateForm, listForm, quoForm';
                $power    = '';
                $word     = true;
                break;
            default:
                $act      = 'del';
                $msg      = '删除' . self::title;
                $title    = self::page . 'Delete';
                $function = 'delete';
                $form     = self::page . 'OperateForm, listForm, quoForm';
                $power    = '';
                break;
        }
        if (!$this->power(self::page, $act)) {
            $_SESSION['warn'] = '你还没有' . $msg . '的权限';
            $json             = [
                'warn' => 2,
                'href' => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=home',
            ];
        } else {
            return $this->confirm([
                'title'    => $title,
                'function' => $function,
                'form'     => $form,
                'power'    => $power,
                'pwd'      => $pwd,
                'word'     => $word,
            ]);
        }

        resp:
        return json_encode($json, 320);
    }

    /**
     * 删除
     *
     * @return bool|string
     */
    public function delete()
    {
        $array = $this->post('listId') ?? $this->post('id');
        if (!$this->power(self::page, "del")) {
            $json['warn'] = "你没有删除的权限";
        } elseif (empty($array)) {
            $json['warn'] = "你一个数据都没有选择呢";
        } else {
            $text  = "";
            $x     = 0;
            $array = is_array($array) ? $array : [$array];
            foreach ($array as $id) {
                $info = query(self::table, " id = '$id' ");
                if ($info['state'] == '已确认') {
                    $warn = "删除失败：已确认，暂不能删除";
                } else {
                    //最后删除基本参数
                    fileClass::deleteFile($id);
                    delete(["table" => self::table, "where" => " id = '$id' "]);
                    delete(["table" => self::tableMx, "where" => " orderId = '$id' "]);
                    delete(["table" => "auditing_follow", "where" => " typeId = '$id' "]);
                    //返回
                    $warn = "删除成功";
                    $x++;
                }
                $text .= self::title . "ID【" . $info['id'] . "】" . $warn . "。<br>";
            }
            //添加日志
            $text = $this->control['name'] . "删除了" . self::title . "，结果如下：<br>" . $text;
            $this->logText(["type" => self::page, "text" => $text]);
            $_SESSION['warn'] = "删除了" . $x . "个" . self::title . "，详情见系统日志。";
            $json['warn']     = 2;
            $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
        }
        return json_encode($json, 320);
    }

    /**
     * 批量关闭销售订单
     *
     * @return bool|string
     */
    public function closeEdit()
    {
        $array = $this->post('listId') ?? $this->post('id');
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有操作的权限";
        } elseif (empty($array)) {
            $json['warn'] = "你一个数据都没有选择呢";
        } else {
            $text  = "";
            $x     = 0;
            $array = is_array($array) ? $array : [$array];
            foreach ($array as $id) {
                $info = query(self::table, " id = '$id' ", "isClose");
                if ($info['isClose'] == 1) {
                    $warn = "操作失败：已关闭，请勿重复操作";
                } else {
                    update(['table' => self::table, 'field' => ['isClose' => 1], 'where' => " id = '$id' "]);
                    update(['table' => 'product_demands', 'field' => ['isClear' => 1], 'where' => " sourceId = '$id' "]);
                    self::insertOperateLog($id, self::title, "关闭");
                    //返回
                    $warn = "关闭成功";
                    $x++;
                }
                $text .= self::title . "ID【" . $id . "】" . $warn . "。<br>";
            }
            //添加日志
            $text = $this->control['name'] . "关闭了" . self::title . "，结果如下：<br>" . $text;
            $this->logText(["type" => self::page, "text" => $text]);
            $_SESSION['warn'] = "关闭了" . $x . "个" . self::title . "，详情见系统日志。";
            $json['warn']     = 2;
            $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
        }
        return json_encode($json, 320);
    }

    public static function getPeriod($type, $day)
    {
        return match ($type) {
            '月结' => $type . '-' . $day,
            default => $type,
        };
    }

    /**
     * 批量打印
     *
     * @return string
     */
    public function batchPrint(): string
    {
        $lists = $this->get('lists');
        if (empty($lists)) {
            exit('参数错误');
        } else {
            $listId = base64_decode($lists, true);
            $array  = explode(',', $listId);
            $data   = [];
            foreach ($array as $id) {
                $data[] = static::printPage($id, false);
            }
            return (new printTemplateClass())->start(self::page, $data);
        }
    }

    /**
     * 打印
     *
     * @return string
     */
    public function printPage($param = '', $isReturn = true): string|array
    {
        $id                  = $param ?: $this->get('id');
        $info                = query(self::table, " id = '$id'");
        $info['companyName'] = query('company', "coid = '" . self::$coid . "'")['name']; //公司名称//公司名称
        $info['title']       = self::title;
        $info['printTime']   = $this->time;
        $info['stid']        = self::findStaff($info['stid']);
        $info['checkId']     = self::findStaff($info['checkId']);
        $info['khName']      = query('kehu', "khid = '$info[khid]'")['companyName'];
        $info['contractId']  = query('sales_contract', "id = '$info[contractId]'")['name'];
        $info['qr']          = "source=" . self::table . "&id=" . $info['id'];
        $info['salemans']    = self::findStaff($info['manager']);
        $info['tags']        = orderTagClass::getTagName($info['id']);
        $detail              = find(['table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list asc"])['array'];
        $items               = [];
        $x                   = 1;
        $totalNum            = 0;
        $totalMoney          = 0;
        foreach ($detail as $array) {
            $material = query('material', "id = '$array[materialId]'");
            $items[]  = [
                'no'              => $x,
                'materialCode'    => $material['code'],
                'materialName'    => $material['name'],
                'price'           => self::lostZero($array['price'], 'pricePrecision'),
                'rate'            => ($array['rate'] * 100) . '%',
                'taxMoney'        => self::lostZero($array['taxMoney'], 'amount'),
                'khMaterialName'  => $array['khMaterialName'],
                'khMaterialCode'  => $array['khMaterialCode'],
                'moneyWithOutTax' => self::formattingFigure($array['money'] - $array['taxMoney'], 'amount'),
                'money'           => self::lostZero($array['money'], 'amount'),
                'model'           => $material['model'],
                'unit'            => $array['unit'],
                'num'             => $array['num'],
                'text'            => $array['text'],
            ];
            $x++;
            $totalNum   += $array['num'];
            $totalMoney += $array['money'];
        }
        $append         = [
            'no'    => '合计',
            'num'   => self::lostZero($totalNum, 'amount'),
            'money' => self::lostZero($totalMoney, 'amount'),
        ];
        $items[]        = $append;
        $info['detail'] = $items;
        if ($isReturn) {
            return (new printTemplateClass())->start(self::page, $info);
        } else {
            return $info;
        }
    }

    /**
     * Desc : 列表文本显示加提示
     * User : you name
     * Date : 2023-11-10 10:39
     * @param $text
     * @param bool $show
     * @param string $tip
     * @param string $tipTitle
     * @return string
     */
    public static function textTips($text, int|bool $show, string $tip = '超', string $tipTitle = '此订单已超期'): string
    {
        $em = '';
        if ($show) {
            $em = "<em style='font-size: 12px;color: red;font-style: normal;cursor: default;' title='{$tipTitle}'>{$tip}</em>";
        }
        return "<span>" . $text . " $em</span>";
    }

    /**
     * 导入模板字段初始化
     * @return array[]
     */
    public function importFieldInit($classify = ''): array
    {
        return match ($classify) {
            default => [
                [
                    'columnName' => '单据日期',
                    'aliasName'  => '单据日期',

                    'isMust' => true,
                ],
                [
                    'columnName' => '客户编码',
                    'aliasName'  => '客户编码',

                    'isMust' => true,
                ],
                [
                    'columnName' => '客户名称',
                    'aliasName'  => '客户名称',

                    'isMust' => false,
                ],
                [
                    'columnName' => '销售合同编号',
                    'aliasName'  => '销售合同编号',

                    'isMust' => false,
                ],
                [
                    'columnName' => '销售合同名称',
                    'aliasName'  => '销售合同名称',

                    'isMust' => false,
                ],
                [
                    'columnName' => '销售员编号',
                    'aliasName'  => '销售员编号',

                    'isMust' => false,
                ],
                [
                    'columnName' => '销售员名称',
                    'aliasName'  => '销售员名称',

                    'isMust' => false,
                ],
                [
                    'columnName' => '交货方式',
                    'aliasName'  => '交货方式(自提/配送，默认自提)',

                    'isMust' => true,
                ],
                [
                    'columnName' => '结算方式',
                    'aliasName'  => '结算方式',

                    'isMust' => true,
                ],
                [
                    'columnName' => '结算周期',
                    'aliasName'  => '结算周期',

                    'isMust' => false,
                ],
                [
                    'columnName' => '交货日期',
                    'aliasName'  => '交货日期',

                    'isMust' => false,
                ],
                [
                    'columnName' => '收货人',
                    'aliasName'  => '收货人',

                    'isMust' => false,
                ],
                [
                    'columnName' => '收货电话',
                    'aliasName'  => '收货电话',

                    'isMust' => false,
                ],
                [
                    'columnName' => '收货地址',
                    'aliasName'  => '收货地址',

                    'isMust' => false,
                ],
                [
                    'columnName' => '单据备注',
                    'aliasName'  => '单据备注',

                    'isMust' => false,
                ],
                [
                    'columnName' => '是否含税',
                    'aliasName'  => '是否含税(是/否，默认否)',

                    'isMust' => true,
                ],
                [
                    'columnName' => '产品编码',
                    'aliasName'  => '产品编码',

                    'isMust' => true,
                ],
                [
                    'columnName' => '产品名称',
                    'aliasName'  => '产品名称',

                    'isMust' => false,
                ],
                [
                    'columnName' => '单位',
                    'aliasName'  => '单位',

                    'isMust' => true,
                ],
                [
                    'columnName' => '数量',
                    'aliasName'  => '数量',

                    'isMust' => true,
                ],
                [
                    'columnName' => '单价',
                    'aliasName'  => '单价',

                    'isMust' => true,
                ],
                [
                    'columnName' => '税率',
                    'aliasName'  => '税率%',

                    'isMust' => true,
                ],
                [
                    'columnName' => '价税合计',
                    'aliasName'  => '价税合计',

                    'isMust' => false,
                ],
                [
                    'columnName' => '客户料号',
                    'aliasName'  => '客户料号',

                    'isMust' => false,
                ],
                [
                    'columnName' => '客户品名',
                    'aliasName'  => '客户品名',

                    'isMust' => false,
                ],
                [
                    'columnName' => '备注',
                    'aliasName'  => '备注',

                    'isMust' => false,
                ],
            ]
        };
    }

}
